Opened 4 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: aaugustin Owned by: aaugustin
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 aaugustin 4 years ago.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 4 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 4 years ago by akaariai

  • 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 4 years ago by akaariai

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 aaugustin

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 aaugustin (previous) (diff)

Changed 4 years ago by aaugustin

comment:6 Changed 4 years ago by aaugustin

  • Has patch set
  • Needs tests set

comment:7 Changed 4 years ago by aaugustin

  • Resolution set to fixed
  • Status changed from new to closed

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