chronotope / chrono-tz

TimeZone implementations for rust-chrono from the IANA database
Other
235 stars 55 forks source link

Get time zone offset around a gap #183

Open acrrd opened 2 weeks ago

acrrd commented 2 weeks ago

I have to transform a NaiveDateTime to a local one; I use from_local_datetime with the target timezone. When the time is ambiguous, I want to keep the earliest. When there is a gap, I want to move the time by the amount of the gap for each time in it. For example, with timezone Europe/Amsterdam:

I did

let time_tz = tz.from_utc_datetime(local_time);
time_tz - time_tz.offset().base_utc_offset()

it works with almost all time zones except for Europe/Dublin and Pacific/Apia (at 2011-12-30 when they changed side w.r.t the international date line).

To make it work, I need to use the offset before the gap

let before_offset = tz.offset_from_utc_datetime(local_time - TimeDelta::hours(72));
time_tz - TimeDelta::seconds(before_offset.base_utc_offset() + before_offset.dst_offset())

Going back an arbitrary amount of time feels like a workaround. It would be nice to have an API that, given a NaiveDateTime returns the timezone offset before the gap. The optimum would be for from_utc_datetime to return something like None(before_offset) instead of just None to avoid a second binary search, but I guess that is out of the question.

Alternatively, is there another solution that I missed?

djc commented 2 weeks ago

I think this was discussed in the chrono issue tracker not too long ago (within the past 6 months maybe?). Would suggest searching that repository -- IIRC it is possible but I forget how.

acrrd commented 2 weeks ago

I found https://github.com/chronotope/chrono/issues/1447, but it is not the same use case. I already have a Tz and a NaiveDateTime as input. There, they do not try to solve the case of the gap, which is what an additional API will help solve in a nicer way. A solution for it is being discussed in https://github.com/chronotope/chrono/issues/1448, adding more information to LocalResult::None will solve the problem.

My request is to add a method to Tz that allows to get the information that is currently missing as a stop-gap solution till chrono 0.5 is hopefully released with a different version of LocalResult.