Add configurable TIMEZONE for web UI display (UTC storage preserved)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
"""Timezone helpers for web UI."""
|
||||
from contextvars import ContextVar
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
_current_timezone: ContextVar[str] = ContextVar("current_timezone", default="UTC")
|
||||
|
||||
|
||||
def set_current_timezone(tz: str) -> None:
|
||||
_current_timezone.set(tz)
|
||||
|
||||
|
||||
def get_current_timezone() -> str:
|
||||
return _current_timezone.get()
|
||||
|
||||
|
||||
def get_common_timezones() -> list[str]:
|
||||
"""Return a curated list of common IANA timezones for the UI."""
|
||||
return [
|
||||
"UTC",
|
||||
"Europe/Moscow",
|
||||
"Europe/Samara",
|
||||
"Asia/Krasnoyarsk",
|
||||
"Asia/Novosibirsk",
|
||||
"Asia/Irkutsk",
|
||||
"Asia/Yakutsk",
|
||||
"Asia/Vladivostok",
|
||||
"Asia/Kamchatka",
|
||||
"Asia/Almaty",
|
||||
"Asia/Tashkent",
|
||||
"Asia/Tbilisi",
|
||||
]
|
||||
|
||||
|
||||
def _ensure_aware(dt: datetime, default_tz: str = "UTC") -> datetime:
|
||||
if dt.tzinfo is None:
|
||||
return dt.replace(tzinfo=ZoneInfo(default_tz))
|
||||
return dt
|
||||
|
||||
|
||||
def localtime(
|
||||
value: Optional[datetime],
|
||||
tz: Optional[str] = None,
|
||||
fmt: str = "%Y-%m-%d %H:%M",
|
||||
) -> str:
|
||||
"""Convert a UTC datetime to the configured timezone and format it."""
|
||||
if value is None:
|
||||
return "-"
|
||||
tz_name = tz or get_current_timezone()
|
||||
try:
|
||||
zone = ZoneInfo(tz_name)
|
||||
except ZoneInfoNotFoundError:
|
||||
zone = ZoneInfo("UTC")
|
||||
dt = _ensure_aware(value)
|
||||
return dt.astimezone(zone).strftime(fmt)
|
||||
|
||||
|
||||
def localtime_iso(value: Optional[datetime], tz: Optional[str] = None) -> str:
|
||||
"""Convert a UTC datetime to the configured timezone and return ISO string."""
|
||||
if value is None:
|
||||
return ""
|
||||
tz_name = tz or get_current_timezone()
|
||||
try:
|
||||
zone = ZoneInfo(tz_name)
|
||||
except ZoneInfoNotFoundError:
|
||||
zone = ZoneInfo("UTC")
|
||||
dt = _ensure_aware(value)
|
||||
return dt.astimezone(zone).isoformat()
|
||||
Reference in New Issue
Block a user