Files
xenia-pos-local/local_backend/tz.py
bonamin 72b12ddd9c fix: fix timezone handling across backend and frontend (v0.3.1)
- Add tz.py with local_strftime/to_local helpers that read system.timezone
  from DB and convert UTC datetimes to venue local time before formatting
- Fix all strftime() calls in orders.py, reports.py, printer_service.py
  that were formatting UTC datetimes without timezone conversion
- Fix get_order endpoint returning raw dicts without Z suffix on datetimes,
  causing JS new Date() to treat timestamps as local instead of UTC
- Fix fmtDate() in tokens.js that stripped the T separator before parsing,
  breaking UTC-to-local conversion for all report date displays
- Make open/partially_paid table chips more visually distinct on dashboard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:18:46 +03:00

40 lines
1.1 KiB
Python

"""Timezone utilities for converting UTC datetimes to the venue's local time."""
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from datetime import datetime, timezone
from database import SessionLocal
from models.settings import PosSettings
_FALLBACK = "Europe/Athens"
def _get_tz_name() -> str:
db = SessionLocal()
try:
row = db.query(PosSettings).filter(PosSettings.key == "system.timezone").first()
return row.value if row and row.value else _FALLBACK
except Exception:
return _FALLBACK
finally:
db.close()
def to_local(dt: datetime) -> datetime:
"""Convert a UTC-aware datetime to the venue's configured local timezone."""
if dt is None:
return dt
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
try:
tz = ZoneInfo(_get_tz_name())
except ZoneInfoNotFoundError:
tz = ZoneInfo(_FALLBACK)
return dt.astimezone(tz)
def local_strftime(dt: datetime, fmt: str) -> str:
"""Format a UTC-aware datetime in local time using the venue's timezone."""
if dt is None:
return ""
return to_local(dt).strftime(fmt)