@@ -0,0 +1,65 @@
|
||||
"""Время для БД и API: колонки DateTime в проекте — naive; договорённость — UTC."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime, timezone
|
||||
from typing import Union
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
_DEFAULT_DISPLAY_TZ = "Europe/Moscow"
|
||||
|
||||
|
||||
def zoneinfo_or_utc(name: str) -> Union[ZoneInfo, timezone]:
|
||||
"""IANA timezone; on Windows without tzdata falls back to UTC for «UTC»."""
|
||||
key = (name or "").strip()
|
||||
if not key or key.upper() in {"UTC", "ETC/UTC", "GMT"}:
|
||||
return timezone.utc
|
||||
try:
|
||||
return ZoneInfo(key)
|
||||
except Exception:
|
||||
if key.upper() in {"UTC", "ETC/UTC", "GMT"}:
|
||||
return timezone.utc
|
||||
raise
|
||||
|
||||
|
||||
def utc_now_naive() -> datetime:
|
||||
"""Текущий момент в UTC без tzinfo (как DateTime в SQLite/SQLAlchemy здесь)."""
|
||||
return datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
|
||||
|
||||
def utc_now_iso() -> str:
|
||||
"""ISO 8601 с явным UTC (+00:00) для JSON и логов."""
|
||||
return datetime.now(timezone.utc).isoformat()
|
||||
|
||||
|
||||
def naive_utc_to_iso(dt: datetime | None) -> str:
|
||||
"""Сериализация naive UTC из БД в ISO с суффиксом +00:00."""
|
||||
if dt is None:
|
||||
return utc_now_iso()
|
||||
if dt.tzinfo is not None:
|
||||
return dt.astimezone(timezone.utc).isoformat()
|
||||
return dt.replace(tzinfo=timezone.utc).isoformat()
|
||||
|
||||
|
||||
def display_timezone_name() -> str:
|
||||
"""IANA-имя зоны для календаря/«сегодня» в UI (из конфига приложения)."""
|
||||
try:
|
||||
from flask import current_app, has_request_context
|
||||
|
||||
if has_request_context():
|
||||
name = current_app.config.get("WESP_DISPLAY_TIMEZONE")
|
||||
if name:
|
||||
return str(name)
|
||||
except Exception:
|
||||
pass
|
||||
return _DEFAULT_DISPLAY_TZ
|
||||
|
||||
|
||||
def display_calendar_today() -> date:
|
||||
"""Сегодняшняя дата в зоне WESP_DISPLAY_TIMEZONE (для диапазонов графиков и т.п.)."""
|
||||
tz_name = display_timezone_name()
|
||||
try:
|
||||
tz = zoneinfo_or_utc(tz_name)
|
||||
return datetime.now(tz).date()
|
||||
except Exception:
|
||||
return datetime.now(timezone.utc).date()
|
||||
Reference in New Issue
Block a user