File size: 2,164 Bytes
bfcc872
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""
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")