JuliaTime / TimeZones.jl

IANA time zone database access for the Julia programming language
Other
86 stars 51 forks source link

next_transition_instant returns wrong transition #396

Closed JakubPorubcansky closed 2 years ago

JakubPorubcansky commented 2 years ago

By creating a ZonedDateTime range with hourly sampling rate like below I can see that the duplicated hour in local time is "02:00:00".

julia> zdt1 = ZonedDateTime(2007, 10, 27, 22, tz"Europe/Budapest")
2007-10-27T22:00:00+02:00

julia> zdt2 = ZonedDateTime(2007, 10, 28, 5, tz"Europe/Budapest")
2007-10-28T05:00:00+01:00

julia> collect(zdt1:Hour(1):zdt2)
9-element Vector{ZonedDateTime}:
 2007-10-27T22:00:00+02:00
 2007-10-27T23:00:00+02:00
 2007-10-28T00:00:00+02:00
 2007-10-28T01:00:00+02:00
 2007-10-28T02:00:00+02:00
 2007-10-28T02:00:00+01:00
 2007-10-28T03:00:00+01:00
 2007-10-28T04:00:00+01:00
 2007-10-28T05:00:00+01:00

However, if I apply the next_transition_instant function to zdt1 and add one hour to it then it seems that the 03:00:00 is duplicated in the local time.

julia> next_transition_instant(zdt1)
2007-10-28T03:00:00+02:00

julia> next_transition_instant(zdt1) + Hour(1)
2007-10-28T03:00:00+01:00

Is this a bug or am I missing something?

omus commented 2 years ago

So what you've noticed isn't a bug but is a quirk of how next_transition_instant works to make show_next_transition work well. For example:

julia> zdt1 = ZonedDateTime(2007, 10, 27, 22, tz"Europe/Budapest")
2007-10-27T22:00:00+02:00

julia> TimeZones.show_next_transition(zdt1)
Transition Date:   2007-10-28
Local Time Change: 03:00 → 02:00 (Backward)
Offset Change:     UTC+1/+1 → UTC+1/+0
Transition From:   2007-10-28T02:59:59.999+02:00 (CEST)
Transition To:     2007-10-28T02:00:00.000+01:00 (CET)

Specifically see how "Transition From" is one millisecond off of your answer from next_transition_instant(zdt1). The result from next_transition_instant isn't incorrect it's just displayed in a strange way which is a feature show_next_transtition is taking advantage of:

julia> using TimeZones, Dates

julia> zdt1 = ZonedDateTime(2007, 10, 27, 22, tz"Europe/Budapest")
2007-10-27T22:00:00+02:00

julia> a = next_transition_instant(zdt1)
2007-10-28T03:00:00+02:00

julia> b = next_transition_instant(zdt1) + Hour(0)  # Forces the resulting `ZonedDateTime` to be "valid"
2007-10-28T02:00:00+01:00

julia> a == b
true

There is a note in the docstring for next_transition_instant about this quirk:

Note that the provided ZonedDateTime isn't normally constructable

I could probably go into more details about this so that it's more obvious. Do you have a specific use case you're trying to solve? Maybe there's a better approach I can help you with if you explain what you're trying to accomplish.

JakubPorubcansky commented 2 years ago

I do not have a specific use case, I just noticed this when working with the package and it seemed strange to me. Now it makes sense, thank you!