Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible edge case around last rule applicable for a zone lines last year #137

Open
ciju opened this issue Aug 24, 2023 · 4 comments
Open

Comments

@ciju
Copy link

ciju commented Aug 24, 2023

Noticed the edge case for Pacific/Apia timezone. This timezone has a shift in offset of about a day in dec 2011. There are also DST rules applicable for the same year. Following are the relevant zone lines.

			 -11:00	WS	-11/-10	2011 Dec 29 24:00
			 13:00	WS	+13/+14

Current implementation ignores the offset change on dec 29th. E.g. The periods generated are:

%{
  until: %{
    utc: "2011-09-24T14:00:00Z",
    standard: "2011-09-24T03:00:00Z",
    wall: "2011-09-24T03:00:00Z"
  },
  zone_abbr: "SST",
  from: %{
    utc: "2011-04-02T14:00:00Z",
    standard: "2011-04-02T03:00:00Z",
    wall: "2011-04-02T03:00:00Z"
  },
  std_off: 0,
  utc_off: -39600
}
%{
  until: %{
    utc: "2012-03-31T14:00:00Z",
    standard: "2012-04-01T03:00:00Z",
    wall: "2012-04-01T04:00:00Z"
  },
  zone_abbr: "WSDT",
  from: %{
    utc: "2011-09-24T14:00:00Z",
    standard: "2011-09-25T03:00:00Z",
    wall: "2011-09-25T04:00:00Z"
  },
  std_off: 3600,
  utc_off: 46800
}

I think the periods should be.

%{
  until: %{
    utc: "2011-09-24T14:00:00Z",
    standard: "2011-09-24T03:00:00Z",
    wall: "2011-09-24T03:00:00Z"
  },
  zone_abbr: "SST",
  from: %{
    utc: "2011-04-02T14:00:00Z",
    standard: "2011-04-02T03:00:00Z",
    wall: "2011-04-02T03:00:00Z"
  },
  std_off: 0,
  utc_off: -39600
}
%{
  until: %{
    utc: "2011-12-30T11:00:00Z",
    standard: "2011-12-30T00:00:00Z",
    wall: "2011-12-30T01:00:00Z"
  },
  zone_abbr: "SST",
  from: %{
    utc: "2011-09-24T14:00:00Z",
    standard: "2011-09-24T03:00:00Z",
    wall: "2011-09-24T03:00:00Z"
  },
  std_off: 3600,
  utc_off: -39600
}
%{
  until: %{
    utc: "2012-03-31T14:00:00Z",
    standard: "2012-04-01T03:00:00Z",
    wall: "2012-04-01T04:00:00Z"
  },
  zone_abbr: "WSDT",
  from: %{
    utc: "2011-12-30T11:00:00Z",
    standard: "2011-12-31T00:00:00Z",
    wall: "2011-12-31T01:00:00Z"
  },
  std_off: 3600,
  utc_off: 46800
}

Link to the zone rules for Pacific/Apia

Haven't checked if this issue applies to any other zones.

@ciju
Copy link
Author

ciju commented Aug 29, 2023

Hey @lau Have confirmed the issue in comparison to browser implementations. E.g.

ls = [
  "2011-12-30T09:00:00Z",
  "2011-12-30T09:59:00Z",
  "2011-12-30T10:00:00Z",
  "2011-12-30T10:59:00Z",
  "2011-12-30T11:00:00Z"
]

ls.map(x => [x, new Intl.DateTimeFormat('sv-SE', {
  timeZone: 'Pacific/Apia', 
  year: 'numeric', 
  month: '2-digit', 
  day: '2-digit', 
  hour: '2-digit', 
  minute: '2-digit', 
  second: '2-digit', 
  hour12: false, 
  timeZoneName: 'short'
}).format(new Date(x))])

returns

[
    ["2011-12-30T09:00:00Z", "2011-12-29 23:00:00 GMT−10"],
    ["2011-12-30T09:59:00Z", "2011-12-29 23:59:00 GMT−10"],
    ["2011-12-30T10:00:00Z", "2011-12-31 00:00:00 GMT+14"],
    ["2011-12-30T10:59:00Z", "2011-12-31 00:59:00 GMT+14"],
    ["2011-12-30T11:00:00Z", "2011-12-31 01:00:00 GMT+14"]
]

Current tzdata implementation

[
  "2011-12-30T09:00:00Z",
  "2011-12-30T09:59:00Z",
  "2011-12-30T10:00:00Z",
  "2011-12-30T10:59:00Z",
  "2011-12-30T11:00:00Z"
]
|> Enum.map(&Timex.parse!(&1, "{ISO:Extended:Z}"))
|> Enum.map(&{&1, Timex.Timezone.convert(&1, "Pacific/Apia")})

returns

[
  {~U[2011-12-30 09:00:00Z], #DateTime<2011-12-30 23:00:00+14:00 +14 Pacific/Apia>},
  {~U[2011-12-30 09:59:00Z], #DateTime<2011-12-30 23:59:00+14:00 +14 Pacific/Apia>},
  {~U[2011-12-30 10:00:00Z], #DateTime<2011-12-31 00:00:00+14:00 +14 Pacific/Apia>},
  {~U[2011-12-30 10:59:00Z], #DateTime<2011-12-31 00:59:00+14:00 +14 Pacific/Apia>},
  {~U[2011-12-30 11:00:00Z], #DateTime<2011-12-31 01:00:00+14:00 +14 Pacific/Apia>}
]

My own attempt has issue at edge case. Will see if I can fix that.

@mathieuprog
Copy link
Contributor

mathieuprog commented Aug 29, 2023

@ciju FYI you may also test and add edge cases here: https://github.com/mathieuprog/tzdb_test which compares the output of date calculations against different time zone libraries. I think tzdata still generates a lot of incorrect dates and these tests would help you fix tzdata errors.

@ciju
Copy link
Author

ciju commented Aug 29, 2023

Didn't know about tz. Guess I will just move to tz for my purpose. Hope tzdata issues are fixed soon, or Timex moves to tz/better options :)

@mathieuprog
Copy link
Contributor

Timex can be replaced by the standard API (which evolved significantly since Timex released). I thought you were tied to Timex and had to fix the tzdata bug:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants