Improve timestamp handling and event navigation
This commit is contained in:
53
server/monlet_server/timeutil.py
Normal file
53
server/monlet_server/timeutil.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
DEFAULT_TIME_ZONE = "UTC"
|
||||
_TIMESTAMP_KEYS = ("observed_at", "opened_at", "resolved_at")
|
||||
|
||||
|
||||
def validate_time_zone(value: str) -> str:
|
||||
name = value.strip() or DEFAULT_TIME_ZONE
|
||||
try:
|
||||
ZoneInfo(name)
|
||||
except ZoneInfoNotFoundError as exc:
|
||||
raise ValueError(f"invalid timezone: {name}") from exc
|
||||
return name
|
||||
|
||||
|
||||
def require_utc_datetime(value: datetime) -> datetime:
|
||||
if value.tzinfo is None or value.utcoffset() is None:
|
||||
raise ValueError("timestamp must include UTC timezone")
|
||||
if value.utcoffset() != timedelta(0):
|
||||
raise ValueError("timestamp must be UTC")
|
||||
return value.astimezone(UTC)
|
||||
|
||||
|
||||
def to_utc(value: datetime) -> datetime:
|
||||
if value.tzinfo is None or value.utcoffset() is None:
|
||||
return value.replace(tzinfo=UTC)
|
||||
return value.astimezone(UTC)
|
||||
|
||||
|
||||
def format_display_datetime(value: str | datetime | None, time_zone: str) -> str:
|
||||
if not value:
|
||||
return ""
|
||||
if isinstance(value, datetime):
|
||||
dt = value
|
||||
else:
|
||||
dt = datetime.fromisoformat(value.replace("Z", "+00:00"))
|
||||
return (
|
||||
to_utc(dt)
|
||||
.astimezone(ZoneInfo(validate_time_zone(time_zone)))
|
||||
.strftime("%Y-%m-%d %H:%M:%S %Z")
|
||||
)
|
||||
|
||||
|
||||
def payload_with_display_times(payload: dict, time_zone: str) -> dict:
|
||||
out = dict(payload)
|
||||
out["time_zone"] = validate_time_zone(time_zone)
|
||||
for key in _TIMESTAMP_KEYS:
|
||||
if payload.get(key):
|
||||
out[f"{key}_display"] = format_display_datetime(payload[key], out["time_zone"])
|
||||
return out
|
||||
Reference in New Issue
Block a user