Opened 5 years ago

Closed 4 years ago

Last modified 4 years ago

#17742 closed Cleanup/optimization (fixed)

`DateTimeField` may not behave very well when it is set or compared to a `date` and time zone support is active

Reported by: Aymeric Augustin Owned by: Aymeric Augustin
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: anssi.kaariainen@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no


Attachments (1)

17742.patch (780 bytes) - added by Aymeric Augustin 4 years ago.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 5 years ago by Aymeric Augustin

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Triage Stage: UnreviewedAccepted

comment:3 Changed 5 years ago by Anssi Kääriäinen

Cc: anssi.kaariainen@… added

Here is a short summary on what I have on this issue:

If you supply a timezone aware datetime into a database query it is converted to a date using .date() This has the effect that the datetime's timezone affects which date is supplied into the database query.

The main reason why this seems wrong is that a datetime's timezone doesn't matter in database queries, only what value it represent in time zone UTC matters. Except, if the same datetime is viewed as a date in the query. Then the date it represents changes based on the time zone aware datetime, not by its UTC time.

I thing converting the datetime to a date in the currently active timezone is less surprising for users. This ensures that in single timezone setups users get the date they expect (now() is never yesterday or tomorrow when viewed as a date). However there is one problem: if you convert a datetime value into a date in the database you get different value than if you do the conversion in Python. I don't know if this is anything to worry about. Currently I would expect most values to be saved in time zone UTC, as that is what you get from Forms (correct me if I am wrong here).

If the decision is made that plain .date() call isn't the right thing to do for datetimes, I think DateField should raise a warning when it gets a non-aware datetime object. If the user supplies a date that is OK.

In addition auto_now/auto_now_add for DateFields should be changed to reflect this change. DateField documentation should mention this change.

comment:4 Changed 5 years ago by Anssi Kääriäinen

I have done some investigation, and I have a convincing reason why the "use currently active time zone for date conversion" choice is the best one: PostgreSQL does that, and they seem to know how to handle timezones correctly. It really does seem like the sanest choice. It should work as expected in one-timezone applications. In true multi-timezone applications the developer must know anyways where and how to use DateFields. Django can't solve this issue in that setting completely.

I before liked the UTC date idea, but that seems to ensure problems for single-timezone users. The nice thing about UTC is getting the same date when doing the conversion in the database as when converting in Python. The solution (for 1.5+) is to have proper date conversions done in the database using the active time zone.

comment:5 Changed 4 years ago by Aymeric Augustin

All other automatic conversions in the database layer use the default time zone. The current time zone is only used in the forms and template layers. For predictability, I'm leaning towards using the default time zone.

For single time zone sites, this doesn't matter, because the current time zone is always the default time zone. For multi time zones sites, I suppose the programmer can understand the issue and create explicitly the date he wants. (Also, I don't see that many use cases for comparing a DateField to a datetime.)

Last edited 4 years ago by Aymeric Augustin (previous) (diff)

Changed 4 years ago by Aymeric Augustin

Attachment: 17742.patch added

comment:6 Changed 4 years ago by Aymeric Augustin

Has patch: set
Needs tests: set

comment:7 Changed 4 years ago by Aymeric Augustin

Resolution: fixed
Status: newclosed

comment:8 Changed 4 years ago by Aymeric Augustin <aymeric.augustin@…>

In [939af5a6548bbbae3838773217aecdee910539e8]:

Fixed a typo in a comment. Refs #17742.

Note: See TracTickets for help on using tickets.
Back to Top