Spaces:
Sleeping
Sleeping
| """ | |
| utils/dates.py — Date parsing and formatting utilities | |
| Functions: | |
| - parse_date(s): Parse common date formats to datetime | |
| - format_date(s): Format date to readable string | |
| """ | |
| from __future__ import annotations | |
| from datetime import datetime | |
| from typing import Any, Optional | |
| def parse_date(s: Any) -> Optional[datetime]: | |
| """ | |
| Parse common date formats to datetime object. | |
| Supports: | |
| - ISO 8601: 2024-12-31T23:59:59 | |
| - Date only: 2024-12-31 | |
| - UK format: 31/12/2024 | |
| Args: | |
| s: Date string or datetime object | |
| Returns: | |
| datetime object or None if parsing fails | |
| """ | |
| if not s: | |
| return None | |
| if isinstance(s, datetime): | |
| return s | |
| # Try common formats | |
| s_str = str(s) | |
| # ISO 8601 with time: 2024-12-31T23:59:59 | |
| if 'T' in s_str and len(s_str) >= 19: | |
| try: | |
| return datetime.strptime(s_str[:19], "%Y-%m-%dT%H:%M:%S") | |
| except Exception: | |
| pass | |
| # ISO 8601 date only: 2024-12-31 | |
| if len(s_str) >= 10 and s_str[4:5] == '-' and s_str[7:8] == '-': | |
| try: | |
| return datetime.strptime(s_str[:10], "%Y-%m-%d") | |
| except Exception: | |
| pass | |
| # UK format: 31/12/2024 | |
| if '/' in s_str and len(s_str) >= 10: | |
| try: | |
| return datetime.strptime(s_str[:10], "%d/%m/%Y") | |
| except Exception: | |
| pass | |
| return None | |
| def format_date(s: Any, *, include_time: bool = False) -> str: | |
| """ | |
| Format date to human-readable string. | |
| Args: | |
| s: Date string, datetime object, or None | |
| include_time: If True, include time if available | |
| Returns: | |
| Formatted date string or "—" if parsing fails | |
| Examples: | |
| >>> format_date("2024-12-31") | |
| '2024-12-31' | |
| >>> format_date("2024-12-31T14:30:00", include_time=True) | |
| '2024-12-31 14:30:00' | |
| """ | |
| d = parse_date(s) | |
| if not d: | |
| return str(s) if s else "—" | |
| # Auto-detect if time should be included | |
| has_time = d.hour or d.minute or d.second | |
| if include_time or has_time: | |
| return d.strftime("%Y-%m-%d %H:%M:%S") | |
| else: | |
| return d.strftime("%Y-%m-%d") | |