Files
site/WESP_REL/app/timeutil.py
T
2026-07-17 12:57:18 +03:00

66 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Время для БД и 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()