Spaces:
Running
Running
Download src/utils/dates.py from Leon4gr45/brain: direct link, hf CLI and curl.
- Browser
- Download file 4.31 kB
-
https://huggingface.co/spaces/Leon4gr45/brain/resolve/main/src/utils/dates.py
- Command line
-
hf download hf://spaces/Leon4gr45/brain/src/utils/dates.py
-
curl -L -o dates.py https://huggingface.co/spaces/Leon4gr45/brain/resolve/main/src/utils/dates.py
4.31 kB
| import calendar | |
| from datetime import datetime, timedelta, timezone | |
| from typing import Optional | |
| import re | |
| _DATE_INPUT_FORMATS = ( | |
| "%d/%m/%Y", | |
| "%Y-%m-%d", | |
| "%Y/%m/%d", | |
| "%d-%m-%Y", | |
| "%B %d, %Y", | |
| "%b %d, %Y", | |
| "%B %d %Y", | |
| "%b %d %Y", | |
| "%d %B %Y", | |
| "%d %b %Y", | |
| "%B-%d-%Y", | |
| "%b-%d-%Y", | |
| "%Y-%m-%dT%H:%M:%S", | |
| "%Y-%m-%dT%H:%M:%S%z", | |
| "%Y-%m-%dT%H:%M:%S.%f", | |
| "%Y-%m-%dT%H:%M:%S.%f%z", | |
| "%Y-%m-%d %H:%M:%S", | |
| "%Y-%m-%d %H:%M:%S%z", | |
| "%Y-%m-%d %H:%M:%S.%f", | |
| "%Y-%m-%d %H:%M:%S.%f%z", | |
| "%I:%M %p on %d %B, %Y", | |
| "%I:%M %p on %d %b, %Y", | |
| ) | |
| _RELATIVE_PATTERNS = ( | |
| (re.compile(r"^yesterday$", re.I), lambda ref: ref - timedelta(days=1)), | |
| (re.compile(r"^tomorrow$", re.I), lambda ref: ref + timedelta(days=1)), | |
| (re.compile(r"^today$", re.I), lambda ref: ref), | |
| (re.compile(r"^last\s+week$", re.I), lambda ref: ref - timedelta(days=7)), | |
| (re.compile(r"^next\s+week$", re.I), lambda ref: ref + timedelta(days=7)), | |
| (re.compile(r"^last\s+month$", re.I), lambda ref: _shift_months(ref, -1)), | |
| (re.compile(r"^next\s+month$", re.I), lambda ref: _shift_months(ref, 1)), | |
| ( | |
| re.compile(r"^(\d+)\s+days?\s+ago$", re.I), | |
| lambda ref, m: ref - timedelta(days=int(m.group(1))), | |
| ), | |
| ( | |
| re.compile(r"^in\s+(\d+)\s+days?$", re.I), | |
| lambda ref, m: ref + timedelta(days=int(m.group(1))), | |
| ), | |
| ( | |
| re.compile(r"^(\d+)\s+weeks?\s+ago$", re.I), | |
| lambda ref, m: ref - timedelta(weeks=int(m.group(1))), | |
| ), | |
| ) | |
| _WEEKDAY_NAMES = { | |
| "monday": 0, | |
| "tuesday": 1, | |
| "wednesday": 2, | |
| "thursday": 3, | |
| "friday": 4, | |
| "saturday": 5, | |
| "sunday": 6, | |
| } | |
| def _shift_months(ref: datetime, delta: int) -> datetime: | |
| month = ref.month - 1 + delta | |
| year = ref.year + month // 12 | |
| month = month % 12 + 1 | |
| day = min(ref.day, [31, 29 if calendar.isleap(year) else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1]) | |
| return ref.replace(year=year, month=month, day=day) | |
| def to_naive_utc(value: datetime) -> datetime: | |
| if value.tzinfo is None: | |
| return value | |
| return value.astimezone(timezone.utc).replace(tzinfo=None) | |
| def parse_date_string(value: Optional[str]) -> Optional[datetime]: | |
| if not value or not isinstance(value, str): | |
| return None | |
| cleaned = value.strip() | |
| for fmt in _DATE_INPUT_FORMATS: | |
| try: | |
| parsed = datetime.strptime(cleaned, fmt) | |
| except ValueError: | |
| continue | |
| return to_naive_utc(parsed) | |
| return None | |
| def normalize_date_string(value: Optional[str]) -> Optional[str]: | |
| if not value or not isinstance(value, str): | |
| return value | |
| parsed = parse_date_string(value) | |
| if parsed is not None: | |
| return parsed.strftime("%d/%m/%Y") | |
| return value.strip() | |
| def resolve_relative_date( | |
| value: Optional[str], | |
| reference_time: Optional[str | datetime] = None, | |
| ) -> Optional[str]: | |
| if not value or not isinstance(value, str): | |
| return value | |
| cleaned = value.strip() | |
| absolute = normalize_date_string(cleaned) | |
| if absolute != cleaned or parse_date_string(cleaned) is not None: | |
| return absolute | |
| if reference_time is None: | |
| return cleaned | |
| if isinstance(reference_time, datetime): | |
| ref = reference_time | |
| else: | |
| ref = parse_date_string(str(reference_time)) | |
| if ref is None: | |
| return cleaned | |
| for pattern, resolver in _RELATIVE_PATTERNS: | |
| match = pattern.match(cleaned) | |
| if not match: | |
| continue | |
| if match.lastindex: | |
| resolved = resolver(ref, match) | |
| else: | |
| resolved = resolver(ref) | |
| return resolved.strftime("%d/%m/%Y") | |
| weekday_match = re.match(r"^(last|this|next)\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$", cleaned, re.I) | |
| if weekday_match: | |
| mode = weekday_match.group(1).lower() | |
| target = _WEEKDAY_NAMES[weekday_match.group(2).lower()] | |
| current = ref.weekday() | |
| if mode == "this": | |
| delta = (target - current) % 7 | |
| elif mode == "next": | |
| delta = (target - current) % 7 or 7 | |
| else: | |
| delta = -((current - target) % 7 or 7) | |
| return (ref + timedelta(days=delta)).strftime("%d/%m/%Y") | |
| return cleaned | |