"""프로젝트 공통 시간대 — 모든 시간은 한국 시간(KST, UTC+9)으로 표시/계산한다. 대한민국은 서머타임(DST)이 없으므로 고정 오프셋 +9 로 충분하다. zoneinfo/tzdata 의존 없이 어디서나 동일하게 동작한다. - DB 의 TIMESTAMPTZ 는 UTC 로 저장되고 psycopg 가 aware datetime(UTC)로 돌려준다. 표시 직전에 `to_kst_iso()` 로 KST 문자열로 변환한다. - "오늘"/"지금" 판정은 `today_kst()` / `now_kst()` 를 쓴다(서버 로컬 TZ 무관). """ from __future__ import annotations from datetime import date, datetime, timedelta, timezone KST = timezone(timedelta(hours=9), name="KST") def now_kst() -> datetime: """현재 시각(KST, tz-aware).""" return datetime.now(KST) def today_kst() -> date: """오늘 날짜(KST 기준).""" return now_kst().date() def now_kst_iso() -> str: return now_kst().isoformat(timespec="seconds") def to_kst_iso(dt: datetime | None, *, timespec: str = "seconds") -> str | None: """datetime → KST ISO 문자열. naive 는 UTC 로 간주 후 변환.""" if dt is None: return None if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) return dt.astimezone(KST).isoformat(timespec=timespec)