38 lines
1.0 KiB
Python
38 lines
1.0 KiB
Python
"""Разбор периода для analytics."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date, datetime, timedelta
|
|
from typing import Optional, Tuple
|
|
|
|
|
|
def parse_iso_date(value: Optional[str]) -> Optional[date]:
|
|
if not value:
|
|
return None
|
|
try:
|
|
return date.fromisoformat(str(value).strip()[:10])
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def resolve_date_bounds(
|
|
date_from: Optional[str],
|
|
date_to: Optional[str],
|
|
) -> Tuple[datetime, datetime]:
|
|
"""Включительно date_from … date_to (конец дня date_to)."""
|
|
today = date.today()
|
|
start_d = parse_iso_date(date_from) or today
|
|
end_d = parse_iso_date(date_to) or start_d
|
|
if end_d < start_d:
|
|
start_d, end_d = end_d, start_d
|
|
start_dt = datetime.combine(start_d, datetime.min.time())
|
|
end_dt = datetime.combine(end_d, datetime.max.time())
|
|
return start_dt, end_dt
|
|
|
|
|
|
def iter_dates_in_range(start_d: date, end_d: date):
|
|
cur = start_d
|
|
while cur <= end_d:
|
|
yield cur
|
|
cur += timedelta(days=1)
|