-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
55 lines (49 loc) · 1.65 KB
/
utils.py
File metadata and controls
55 lines (49 loc) · 1.65 KB
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
from datetime import datetime, date
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
import os
def get_tz():
tzname = os.getenv("TIMEZONE", "UTC")
try:
return ZoneInfo(tzname)
except ZoneInfoNotFoundError:
return ZoneInfo("UTC")
def today_local():
return datetime.now(get_tz()).date()
def parse_iso_date(dstr):
# Accept 'YYYY-MM-DD' or ISO with Z/offset
if not dstr:
return None
try:
if 'T' in dstr:
# Handles ISO 8601 format like "2025-10-05T14:48:00.000Z"
return datetime.fromisoformat(dstr.replace('Z', '+00:00')).astimezone(get_tz()).date()
# Handles simple date format like "2025-10-05"
return date.fromisoformat(dstr)
except (ValueError, TypeError):
return None
def normalize_and_format_date(value: object | None) -> str | None:
"""Normalizes a date from various formats into an ISO string."""
if value is None:
return None
dt = None
if isinstance(value, (int, float)):
try:
dt = datetime.fromtimestamp(float(value))
except (ValueError, OSError):
return None
elif isinstance(value, str):
candidate = value.strip()
if not candidate:
return None
try:
# Handles full ISO 8601 format
dt = datetime.fromisoformat(candidate.replace('Z', '+00:00'))
except ValueError:
try:
# Handles simple 'YYYY-MM-DD'
dt = datetime.strptime(candidate, '%Y-%m-%d')
except ValueError:
return None
if dt:
return dt.isoformat(timespec="seconds")
return None