from __future__ import annotations
from sedate import standardize_date, to_timezone
from sqlalchemy.types import DateTime, TypeDecorator
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from datetime import datetime
from sqlalchemy.engine.interfaces import Dialect
[docs]
_Base = TypeDecorator[datetime]
else:
_Base = TypeDecorator
[docs]
class UTCDateTime(_Base):
""" Stores dates as UTC.
Internally, they are stored as timezone naive, because Postgres takes
the local timezone into account when working with timezones. Values taken
and values returned are forced to be timezone-aware though.
"""
def __init__(self) -> None:
super().__init__(timezone=False)
[docs]
def process_bind_param( # type:ignore[override]
self,
value: datetime | None,
dialect: Dialect
) -> datetime | None:
if value is None:
return None
return to_timezone(value, 'UTC').replace(tzinfo=None)
[docs]
def process_result_value(
self,
value: datetime | None,
dialect: Dialect
) -> datetime | None:
if value is None:
return None
return standardize_date(value, timezone='UTC')