#32661 closed Cleanup/optimization (invalid)
An exception should be raised when trying to save datetime/time object and the UTC offset isn't known.
Reported by: | Armin Stepanjan | Owned by: | Abhyudai |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | timezone, datetime, datetimefield, timefield, models |
Cc: | Aymeric Augustin | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
As tzinfo is currently dropped silently from TimeField it leads to tricky bugs for users who expect TimeField to have consistent behaviour with DateTimeField.
This issue suggests two changes, happy to make a PR if the community aggrees with them:
- Mention that TimeField drops timezone in Model field reference: https://docs.djangoproject.com/en/3.2/ref/models/fields/#timefield
- Throw a warning when a TimeField with tzinfo is saved (similarly as there's a warning when a naive DateTimeField is saved).
Change History (11)
comment:1 by , 4 years ago
Cc: | added |
---|---|
Easy pickings: | unset |
Summary: | Make lack of timezone support in TimeField more explicit. → An exception should be raised when trying to save an aware time object. |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 4 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 3 years ago
Has patch: | unset |
---|---|
Needs tests: | unset |
Owner: | changed from | to
Patch needs improvement: | unset |
comment:6 by , 3 years ago
Summary: | An exception should be raised when trying to save an aware time object. → An exception should be raised when trying to save an aware datetime/time object even when the UTC offset isn't known. |
---|
I double checked, this issue is more tricky and DateTimeField
s are also affected. tzinfo
subclasses may not specify the UTC offset (e.g. pytz.timezone("Europe/Paris")
), in such cases we need to also check tzinfo
.
comment:7 by , 3 years ago
Needs tests: | set |
---|---|
Patch needs improvement: | set |
comment:9 by , 3 years ago
Needs tests: | unset |
---|---|
Patch needs improvement: | unset |
comment:10 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | assigned → closed |
datetime
/time
objects with tzinfo
which don't declare utcoffset
should be treated as naive. Closing as invalid per Aymeric's comment:
This code has been working well for over 10 years so let's be careful. Here's my analysis. The docs say: > A datetime object d is aware if both of the following hold: > > 1. d.tzinfo is not None > 2. d.tzinfo.utcoffset(d) does not return None > > Otherwise, d is naive. This hasn't changed this Python 2.7. (I didn't check further back.) This was explicitly the implementation before 432678dbc1dd4f80203468d83bb0eb6c20ed5247. Also, the documentation of datetime.utcoffset, `value.utcoffset()` literally implemented as `None if value.tzinfo is None else value.tzinfo.utcoffset(value)`. As a consequence of the above, each of the following propositions are strictly equivalent: ... Therefore I believe the change proposed here is wrong for at least three reasons: - Any logic changes in this area will diverge from the definition in the Python docs. - The proposed logic is redundant — if `value.tzinfo is None`, then `value.utcoffset() is None`: this is the first six words of the documentation of datetime.utcoffset: "If tzinfo is None, returns None"; I don't see how adding this redundant logic is an improvement. - The proposed logic is wrong — if you wanted to go back to the previous implementation, you should use `and` instead of `or` in `is_naive`. Finally, I believe that have two one-liner convenience functions implemented as `value.utcoffset() is None` and `value.utcoffset() is not None` is fine. I don't see the need for adding a level of indirection and the overhead of a function call here.
comment:11 by , 3 years ago
Summary: | An exception should be raised when trying to save an aware datetime/time object even when the UTC offset isn't known. → An exception should be raised when trying to save datetime/time object and the UTC offset isn't known. |
---|
It's already documented that: "Django only supports naive time objects and will raise an exception if you attempt to save an aware time object, as a timezone for a time with no associated date does not make sense."
Django should raise an exception if you attempt to save an aware time object (at least on Oracle, MySQL, and SQLite), however it looks that
timezone.is_aware()
doesn't work fordatetime.time
.Maybe it's enough to check
tzinfo
.