leroycep / zig-tzif

TZif parsing for Zig
MIT License
8 stars 2 forks source link

UTC offset from POSIX rule #4

Closed FObersteiner closed 9 months ago

FObersteiner commented 9 months ago

https://github.com/leroycep/zig-tzif/blob/e1467e5f6659fb9da719b8cec419128021c4cf30/tzif.zig#L718

POSIX rules give the standard offset in hours West of Greenwich. However, UTC offsets are "normally" presented in hours(:minutes) East of Greenwich, e.g. as specified by ISO8601, +01:00 means the datetime is 1 hour ahead (in Earth's rotation) of UTC.

Your parser currently returns seconds West, but incorrectly - if I didn't miss something! For example, America/Denver with rule "MST7MDT,M3.2.0,M11.1.0" is 7 hours (25200 s) behind (West of) UTC during standard time but only 6 hours (21600 s) behind UTC during DST since DST is +1 hour East.

I can have a deeper look into this and make a PR if you like.

leroycep commented 9 months ago

Ohhh, that is confusing. I would to happy to merge a pull request if you have the time.

FObersteiner commented 9 months ago

I've made a draft here: https://github.com/leroycep/zig-tzif/pull/6

Turns out this is some rabbit hole to go down... Before I can proceed with this, I'll have to get a clear understanding of your concept :)

leroycep commented 9 months ago
  • The method PosixTZ.offset() - is it supposed to take Unix time in seconds and return the corresponding UTC offset of given time zone? Is that correct?

Yep, that's correct. It takes a unix timestamp in seconds and returns what the UTC offset is at that time based on the rules around Daylight Saving Time.

  • Same goes for TimeZone.localTimeFromUTC() I suppose? (--> Unix time + corresponding UTC offset)

And this is also correct, if I understand what you're saying. It takes a Unix timestamp in UTC and converts it into a timestamp in the given timezone.

FObersteiner commented 9 months ago

right, I think the missing part was subtracting the offset, which you have now added here

            const start_dst = range.start.toSecs(utc_year) - this.std_offset;
            const end_dst = range.end.toSecs(utc_year) - this.dst_offset;