jazzband / django-recurrence

Utility for working with recurring dates in Django.
https://django-recurrence.readthedocs.org/
BSD 3-Clause "New" or "Revised" License
491 stars 190 forks source link

Saving in 'UTC' problem with DST #247

Open bonokl opened 1 year ago

bonokl commented 1 year ago
    I don't know if #191 solves the problem.

Imagine this: server timezone is 'UTC', and user's timezone is 'Europe/Berlin' (+01:00 or +02:00 depending on the time of the year). Let's say user needs daily occurrences between 29.10. and 2.11. at 16:00h. User is creating a recurrence on 26.10. when his timezone is +02:00 compared to UTC. Current implementation will save dtstart as 14:00 UTC. And as result user would get next occurrences: 2022-10-29 14:00 UTC => 2022-10-17 16h Europe/Berlin (+02:00) 2022-10-30 14:00 UTC => 2022-10-17 16h Europe/Berlin (+02:00) 2022-11-01 14:00 UTC => 2022-10-17 15h Europe/Berlin (+01:00) 2022-11-02 14:00 UTC => 2022-10-17 15h Europe/Berlin (+01:00)

Because once the time is converted to UTC we don't know which time user wanted.

https://webis.helpshift.com/hc/en/3-pocket-informant/faq/177-recurring-events-and-daylight-saving-time-1634048685/

it should follow rule of the "creation" time zone, not server/UTC timezone,

Originally posted by @bonokl in https://github.com/jazzband/django-recurrence/issues/174#issuecomment-1325149005

one of the possible ideas can be some kind of setting attribute where user can decide whether to save all data as UTC or as it is

tbrlpld commented 1 year ago

I was just wondering about the same. Is there any start time saved by the widget? I am not really seeing an input for a start time on the widget.

I am assuming now that one would always need a dedicated field for a start time and creation timezone on the model. Then you combine the start time and the original timezone and set as the dtstart of the Recurrence.

lino commented 1 month ago

Wouldn't the sensible way be to always use UTC for representing the date and then converting it to the users time zone? Because the users time zone is the one that's changing due to daylight saving time. Also getting the daylight saving time right is incredibly hard as the rules differ by country and sometimes even by province or worse.

tbrlpld commented 1 month ago

What the OP describes is saving in UTC and then displaying in the user time zone.

That is actually the source of "the problem". The user who defines the recurrence always thinks in local time. They don't care about daylight savings and UTC. What they want is that the reminder is always 16:00 local time.

I am not sure this can be solved without taking the original creation time zone into consideration.


Edit: Looks like that's already discussed in #174

lino commented 1 month ago

As soon as time zones are involved there are no right decisions, no matter what you do, you always face a lot of problems. If the user/developer wants to store time in a time zone other than UTC, it's going to cause a lot of edge cases most people won't even think about. So what's the problem here? Django has a way to store a default time zone. Good practice is to also store a time zone for the user. It should not be within the scope of the library to store the individual time zone of a recurrence, as this will cause a whole new set of problems when the user at one point decides to switch time zones. This is also the reason why it's generally not a good idea to store time in something other than UTC unless you are 100% sure that time zones will never concern you. (Spoiler alert: they will)

So what can we do apart from improving documentation and maybe add more syntactic sugar to make your life easier?