DateTime and timezone awareness
See original GitHub issueI’m pulling my hair with datetime TZ awareness issues.
I initiate the connection to MongoDB with tz_aware = False
. I’m no expert about this, and I had never thought much about it before now, but from what I gathered, it seems like a reasonable choice to make. Besides, it’s pymongo
’s default (but flask-PyMongo’s hardcodes tz_aware
to True
).
When a document is pulled from the DB, its DateTimeField
attribute’s TZ awareness depends only on MongoClient
’s tz_aware
parameter (no Marshmallow schema involved):
tz_aware=True
-> pymongo provides an aware datetime -> umongo returns an aware datetime
tz_aware=False
-> pymongo provides a naive datetime -> umongo returns a naive datetime
This is one more reason to set tz_aware = False
, because I’m passing a document/object to a lib that expects a naive timezone. (OAuth2 lib expects expires
timestamp to be naive and compares it to datetime.utcnow()
(see code).) I suppose I could alternatively modify my getters to make all datetime
s naive before returning tokens/grants, but on some use cases, it could get cumbersome.
Marshmallow, however, returns every datetime
as TZ aware (doc). For this reason, umongo’s DateTimeField
’s _deserialize
method returns a TZ aware datetime
. Since I’m using it (via webargs) to parse the inputs to my API, I’m getting TZ aware datetime
s. Likewise, calling load()
on a document will use _deserialize
and result in a TZ aware datetime
.
So if I load a date, it becomes TZ aware. Therefore, to compare it to a date from the database, this one needs to be aware as well.
Should I understand that umongo is meant to be used with tz_aware=True
, so that dates fetched from the database can be compared to dates loaded thought Marshmallow schemas?
Could there be a flag/meta allowing to specify if a DateTimeField
should return a naive datetime
?
I made a quick and dirty patch to DateTime
’s _deserialize
to remove the TZ from the returned output.
dt = super()._deserialize(value, attr, data)
return dt.replace(tzinfo=None)
This seems to work on my use case. However, the day we complete pure Marshmallow schema export, the exported schema I pass to webargs for API input parsing won’t have that feature. Unless this is added to Marshmallow as well. (I asked there about it there: https://github.com/marshmallow-code/marshmallow/issues/520.)
Feedback welcome. Those TZ issues are new to me, so I may be totally misguided.
Issue Analytics
- State:
- Created 7 years ago
- Comments:11 (3 by maintainers)
Top GitHub Comments
Yeah, that’s what I meant -
date.astimezone
returns a new date, it doesn’t have side effects/mutate the date.#75 is merged, @nedwill thanks for pointing this 👍