Skip to content

Compare the UTC UNTIL of VTIMEZONE rules in UTC - #111

Merged
OzzyCzech merged 2 commits into
mainfrom
fix/guesser-until
Sep 28, 2026
Merged

OzzyCzech merged 2 commits into
mainfrom
fix/guesser-until

Conversation

@OzzyCzech

Copy link
Copy Markdown
Owner

Closes #110

TimezoneGuesser::transitions() expanded observance rules with local times read as UTC, but UNTIL is in UTC (RFC 5545, section 3.3.10). East of UTC the last transition of a rule that ended was dropped, so e.g. Europe/Moscow before 2011 under a non-IANA TZID did not resolve; west of UTC a transition after UNTIL could be kept and match a wrong zone.

Rules (and RDATEs, DTSTART) are now expanded in a fixed-offset zone of TZOFFSETFROM, so the Expander returns UTC timestamps and compares UNTIL correctly.

Tests

  • resolvers.phpt: a hand-written Europe/Moscow 2008–2013 definition under Custom/Moscow resolves for reference dates 2010 and 2011 with the right offsets; a west-of-UTC definition whose daylight rule ends before its 2010 transition is no longer matched to America/New_York. Both fail without the fix.
  • vtimezone-builder.phpt: definitions from VTimezoneBuilder with UNTIL (Europe/Moscow, Europe/Minsk, America/Sao_Paulo, Europe/Istanbul) under a renamed TZID resolve to the same transitions as PHP for every reference year.
  • A scratch check over all PHP timezones and three ranges (renamed TZID, no X-LIC-LOCATION): 203 of 5028 cases failed before, 0 after.
  • composer check passes; golden fixtures unchanged.

TimezoneGuesser expanded observance rules with local times read as UTC,
but UNTIL is in UTC (RFC 5545, section 3.3.10). East of UTC the last
transition of a rule that ended was dropped, so e.g. Europe/Moscow before
2011 under a non-IANA TZID did not resolve; west of UTC a transition after
UNTIL could be kept. Rules are now expanded in the fixed TZOFFSETFROM
offset, which gives UTC timestamps.

Across all PHP timezones and three ranges, definitions from
VTimezoneBuilder under a renamed TZID now resolve to the same transitions
(203 of 5028 cases failed before).

Closes #110
…ances

The fixed-offset zone rounded local mean time offsets like +001932 to
minutes, so every transition was off by the rounding and no IANA timezone
matched (e.g. Europe/Amsterdam 1934-1940). PHP timezones keep seconds.

Refs #110
@OzzyCzech
OzzyCzech merged commit a721a36 into main Sep 28, 2026
14 checks passed
@OzzyCzech
OzzyCzech deleted the fix/guesser-until branch September 28, 2026 19:10
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 this pull request may close these issues.

TimezoneGuesser compares UTC UNTIL with local times, drops the last transition east of UTC

1 participant