pbogut / recurring_events

Elixir library for dealing with recurring events
MIT License
26 stars 8 forks source link

library does not respect DST boundaries (no timezone awareness) #14

Open bgentry opened 6 years ago

bgentry commented 6 years ago

In the following example:

iex(47)> {:ok, last_time, _} = DateTime.from_iso8601("2018-11-02T12:04:07Z")                                                
{:ok, #<DateTime(2018-11-02T12:04:07Z Etc/UTC)>, 0}

iex(48)> last_time = Timex.Timezone.convert(last_time, "America/Los_Angeles")                                               
#<DateTime(2018-11-02T05:04:07-07:00 America/Los_Angeles)>

iex(49)> RecurringEvents.take(last_time, %{freq: :daily, by_hour: 3, by_minute: 0, by_second: 0}, 5)                        
[#<DateTime(2018-11-02T05:04:07-07:00 America/Los_Angeles)>,
 #<DateTime(2018-11-03T03:00:00-07:00 America/Los_Angeles)>,
 #<DateTime(2018-11-04T03:00:00-07:00 America/Los_Angeles)>,
 #<DateTime(2018-11-05T03:00:00-07:00 America/Los_Angeles)>,
 #<DateTime(2018-11-06T03:00:00-07:00 America/Los_Angeles)>]

I'm starting with a time that's just before the US daylight saving time switch (Sunday Nov 4th), and explicitly setting it to America/Los_Angeles (UTC-7). The correct behavior would, I think, have the following value for Nov 4th:

2018-11-04T03:00:00-08:00 America/Los_Angeles)

The intention of the provided arguments is to have an event that repeats at 3am every day in the given timezone. But since this package has no timezone or DST awareness, it continues with a UTC-7 offset even though the specified zone has switched to UTC-8.

pbogut commented 6 years ago

Yes, well, this lib is not aware of timezone at all. To be honest this is something I could use in one project, but I would have to wrap my head around timezone's and figure out way to implement it. Will think about it. You could also create PR, looks like you have better idea about handling timezone then I do..

bgentry commented 6 years ago

@pbogut in order to implement this, I think you'd probably end up taking a dependency on something like Timex, which has a lot of functions that provide awareness of timezones. There's an issue on that project to add a recurring event function, which I chimed in on: https://github.com/bitwalker/timex/issues/129

I'm not sure if there's a function that makes it easy to detect whether you've just jumped across a DST boundary, but I think that's what you'd need to detect here. An awful/inefficient way to do this is to convert the new time to UTC, then back to the named timezone and see if it matches the original offset. Ugly though :)

Actually, the Timex.TimezoneInfo module does have some functions which could help here. Also Timex.Timezone.get/2 lets you get a TimezoneInfo by name + datetime. So perhaps every time you generate a new value, you run its timezone name through this function to see if the offset has changed from the previous value (based on the datetime generated).

I may get a chance to come back to this problem in the near future. Would you be interested in adopting Timex as a dependency in order to solve this?

pbogut commented 6 years ago

I was thinking something similar, checking timezone offset every new value. There may be some edge cases when timezone actually will change date, need to check similar modules for different languages how they solve that. As for Timex I'am happy to use it as an optional dependency, I mean, if someone doesn't need timezone handling there is no reason to include Timex.

pbogut commented 6 years ago

I may be talking some rubbish, I guess date will be alrigh. There will be 2 cases, fix timezone if changed for given date (as time is actually all right), or fix time if there is interval rule for time (like every 3 hours) as that will be affected by timezone. Anything else?

pbogut commented 6 years ago

@bgentry Hi, if you are still interested I just started to work on this. If you could provide me with more test cases that would be awesome and would help a lot. You can check #15 to see what I'm trying to do.

bgentry commented 6 years ago

@pbogut yes, absolutely interested in helping. I'll chime in on that thread!