Skip to content

Update timezone data from tzdata 2022g to 2025b#37835

Open
ohbadiah wants to merge 4 commits into
MaterializeInc:mainfrom
ohbadiah:nickmcavoy/cs-639-update-outdated-timezone-data
Open

Update timezone data from tzdata 2022g to 2025b#37835
ohbadiah wants to merge 4 commits into
MaterializeInc:mainfrom
ohbadiah:nickmcavoy/cs-639-update-outdated-timezone-data

Conversation

@ohbadiah

@ohbadiah ohbadiah commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Closes DB-180

Motivation

A customer reported stale timezone data in pg_timezone_names: every mismatch traced to IANA rule changes from 2023 onward (Egypt reinstated DST, Kazakhstan unified on UTC+5, Paraguay abolished DST, Greenland adopted EU DST rules). Timezone data is compiled into the binary via the chrono-tz crate, which was pinned at a 2023 release carrying tzdata 2022g.

What's here

  1. The bump: chrono-tz 0.8.1 → 0.10.4, moving the compiled-in IANA data from 2022g to 2025b (the newest any published chrono-tz carries).
  2. Two API adaptations: Tz::from_str errors became structured (convert explicitly in proto deserialization; one parse error's wording changes). abbreviation() now returns an Option because tzdata 2024b stopped encoding numeric forms like +05 as abbreviations. The Datum conversion would have silently turned that into NULL in pg_timezone_names.abbrev, whose type is declared non-nullable. Instead, render the numeric form from the offset following zic's %z rules, which is what PostgreSQL displays.
  3. Lint and expectation fallout: renew deny.toml's duplicate-phf exception (chrono-tz moved phf 0.11 → 0.12), update the mz_timezone_names row count in EXPLAIN snapshots (tzdata 2025a added America/Coyhaique).
  4. Differential-test overhaul: the postgres snapshot CSVs dated from 2023 and a postgres whose tzdata did not match ours, so real bugs were indistinguishable from version skew, and 29 mismatches sat in an allowlist. regenerate.sh now dumps a postgres container whose /usr/share/zoneinfo is built by zic from exactly the IANA release chrono-tz embeds, with the clock faked via libfaketime. With version skew impossible, the allowlist is deleted: any mismatch fails the test.
  5. New assertions in timezone.slt: the changed zones at summer and winter instants (also pinning numeric-abbreviation rendering, e.g. Asia/Kathmandu's +0545), plus historical pins (Almaty pre-unification, Egypt's first reinstated DST summer, Choibalsan's rewritten past).

Suggested review order

  1. Cargo.toml, deny.toml — the bump and its lint exception.
  2. src/proto/src/chrono.rs, then src/expr/src/scalar/func.rs — the API adaptations. The second is the interesting review.
  3. src/environmentd/tests/testdata/timezones/regenerate.sh — read before the test changes.
  4. src/environmentd/tests/timezones.rs — new header, allowlist removal.
  5. test/sqllogictest/timezone.slt — new assertions. The other slt files are two-line expectation updates.
  6. The CSVs — regenerated data; skim or trust the script.

Verification

The differential test passes with zero tolerated mismatches, both sides pinned to tzdata 2025b. New slt assertions were cross-checked against system tzdata via zdump. Timezone slt files, clippy, and a workspace check run locally; the full battery is CI's.

Known limitation, deliberate: 2025b is the newest data any published chrono-tz release carries, while IANA is at 2026c (Alberta and Morocco moved to permanent offsets in 2026). Delivering newer data independently of upstream's release cadence is tracked as follow-up work.

This release will update the IANA timezone database from 2022g to 2025b, correcting timezone rules changed since 2023 (Egypt, Kazakhstan, Paraguay, Greenland) and rendering numeric timezone abbreviations (e.g. +05) in pg_timezone_names for zones without alphabetic ones.

🤖 Generated with Claude Code

ohbadiah and others added 4 commits July 24, 2026 02:35
Bump chrono-tz 0.8.1 to 0.10.4, which carries IANA tzdata 2025b. This
picks up rule changes since 2023: Egypt reinstated DST, Kazakhstan
unified on UTC+5, Paraguay abolished DST, and Greenland adopted EU DST
rules.

Two adaptations to chrono-tz API changes:

* Tz::from_str now fails with a structured ParseError instead of a
  String.
* OffsetName::abbreviation returns an Option because tzdata 2024b+ no
  longer encodes numeric forms like "+05" as abbreviations. Render the
  numeric form from the offset when absent, matching PostgreSQL. This
  keeps pg_timezone_names.abbrev non-null.

Add regression tests pinning the changed zones and the numeric
abbreviation rendering.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Renew the deny.toml duplicate-phf exception for chrono-tz's move from
phf 0.11 to 0.12. Accept the new timezone parse error wording from
chrono-tz's structured ParseError. Update the mz_timezone_names row
count in EXPLAIN snapshots for tzdata 2025a's America/Coyhaique.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Postgres timezone data shapshots are now dumped from a postgres seeded
with exactly the IANA release chrono-tz compiles in, rather than from a
laptop with sudo date and whatever tzdata it had.

That improved mechanism allows us to remove exceptions from the test
that our zones match.

Add slt assertions for the zone rules changed since 2023, and for
historical instants that must keep their old rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ohbadiah
ohbadiah marked this pull request as ready for review July 24, 2026 16:54
@ohbadiah
ohbadiah requested review from a team as code owners July 24, 2026 16:54
@ohbadiah
ohbadiah enabled auto-merge (squash) July 24, 2026 16:54

@antiguru antiguru left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One risk of this PR is that we've previously ingested data with a time zone, casted it to the specific Materialize type, and now see a retraction of the value. The timezone parsing could change, leaving us with invalid retractions. This can only happen through the storage scalar expr, which calls into strconv to parse dates etc. In some sense, this is a backwards-incompatible change to our source ingestion.

@antiguru
antiguru disabled auto-merge July 24, 2026 17:27
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.

2 participants