spoqa / sqlalchemy-utc

SQLAlchemy type to store aware datetime values
https://pypi.python.org/pypi/SQLAlchemy-Utc
MIT License
101 stars 20 forks source link

Clarification on usage of sqlalchemy-utc #16

Open raph90 opened 2 years ago

raph90 commented 2 years ago

Hi, I just wanted to check that I understand the use of this library so that I can use it correctly in my application. From what I understand:

Is that correct?

dahlia commented 2 years ago

DateTime from SQLAlchemy is one of vendor-neutral “generic types,” which means its behavioral details depend on the engine (e.g., SQLite or PostgreSQL) and vary at runtime. In general, DateTime(timezone=True) assumes a value is an aware datetime, whereas DateTime(timezone=False) assumes it's a naive datetime.[^1] However, it's undefined if DateTime(timezone=True) takes a naive one or DateTime(timezone=False) takes an aware one, and it actually behaves quite differently on various engines. SQLite engine even ignores timezone offsets whether it's DateTime(timezone=True) or DateTime(timezone=False).

On the other hand, UtcDateTime does not take any naive datetime values at all. It explicitly rejects them.

UtcDateTime's another function is that it normalizes offsets of aware datetimes into zero (i.e., UTC). It does not mean their offsets are merely dropped, but their offset timestamps are shifted to the equivalent UTC timestamps. For example, datetime(2022, 3, 27, 3, 5, 50, tzinfo=timezone(timedelta(hours=9))) is normalized to datetime(2022, 3, 26, 18, 5, 50, tzinfo=timezone.utc).

[^1]: Although Python datetime's such dualism is generally considered an architectural flaw, every Python programmer anyway has to deal with it.