27 lines
736 B
Python
27 lines
736 B
Python
|
|
"""Canonical UTC time helpers (RMGR-ADR-002)."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from datetime import UTC, date, datetime
|
||
|
|
|
||
|
|
|
||
|
|
def utc_now() -> datetime:
|
||
|
|
"""Return the current timezone-aware UTC instant."""
|
||
|
|
return datetime.now(UTC)
|
||
|
|
|
||
|
|
|
||
|
|
def format_utc(value: datetime) -> str:
|
||
|
|
"""Serialize an aware instant as canonical RFC 3339 UTC with ``Z``."""
|
||
|
|
if value.tzinfo is None or value.utcoffset() is None:
|
||
|
|
raise ValueError("timestamp must be timezone-aware")
|
||
|
|
return value.astimezone(UTC).isoformat().replace("+00:00", "Z")
|
||
|
|
|
||
|
|
|
||
|
|
def utc_now_text() -> str:
|
||
|
|
return format_utc(utc_now())
|
||
|
|
|
||
|
|
|
||
|
|
def utc_today() -> date:
|
||
|
|
"""Return the calendar date derived from the current UTC instant."""
|
||
|
|
return utc_now().date()
|