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
|
from __future__ import annotations
from datetime import UTC, date, datetime, time, timedelta
def ensure_utc(dt: datetime) -> datetime:
if dt.tzinfo is None:
return dt.replace(tzinfo=UTC)
return dt.astimezone(UTC)
def parse_date(value: str) -> date:
return date.fromisoformat(value)
def parse_datetime(value: str) -> datetime:
normalized = value.replace("Z", "+00:00")
return ensure_utc(datetime.fromisoformat(normalized))
def date_range(start: date, end: date) -> list[date]:
days: list[date] = []
current = start
while current <= end:
days.append(current)
current += timedelta(days=1)
return days
def year_bounds(year: int) -> tuple[date, date]:
return date(year, 1, 1), date(year, 12, 31)
def date_to_utc_bounds(value: date) -> tuple[datetime, datetime]:
start = datetime.combine(value, time.min, tzinfo=UTC)
end = datetime.combine(value, time.max, tzinfo=UTC)
return start, end
|