zdump-rs — a bounded, independent TZif witness (companion to zic-rs)
zic-rsis the compiler.zdump-rsis the witness/inspection companion. It is deliberately not a fullzdumpreplacement — it is a narrow, independent Rust TZif reader that renders what a TZif file means (offset / is_dst / abbreviation) at explicit instants, as deterministic JSON witness rows, so the evidence court has a second, independently-written reader to cross-check against referencezdump.
Milestone: T23.zdump-witness.1 (Phase 1) · .2 (Phase 2) · .3 (Phase 3, current) — inside
the zic-rs T23 evidence surface, not a new top-level milestone.
Published crate: https://crates.io/crates/zdump-rs · source: https://github.com/infinityabundance/zdump-rs (GitHub "No releases published" refers to GitHub Releases only — the crate is published on crates.io.)
Why it exists
Today zic-rs uses reference zdump as its semantic oracle (correct). A separate Rust reader adds an
independent witness — sharing no code with zic-rs's own tzif module, so agreement between the two is
real evidence, not a tautology. It is especially useful for right/-leap rendering, future Appendix-A
microcases, golden TZif inspection, and eventual no-reference-zdump environments.
The evidence court now has four distinct roles:
compiler: zic-rs
format validator: zic-rs rfc9636::validate
oracle comparison: reference zdump
independent Rust witness: zdump-rs <-- this crate
What it does
Phase 1:
- reads TZif v1/v2/v3/v4 (independent, bounds-checked reader; truncated/hostile input →
Err, never a panic) - evaluates UT offset / is_dst / abbreviation at explicit UTC instants
- emits deterministic JSON witness rows (fixed field order)
Phase 2:
- interprets the POSIX footer — instants beyond the last explicit transition are projected
(offset/is_dst/abbreviation), matching reference
zdumpfar-future instead of guessing - lists transitions over a year window (the
zdump -vanalog: instant + before/after type) - exposes the leap-second table (
--leaps)
Phase 3 (partial zdump CLI compatibility):
- named-zone resolution — pass
America/New_York(no--tzif), resolved under$TZDIR/--tzdir -c lo,hiyear-cut (thezdump -cflag)- leap-second
23:59:60rendering forright/zones — the inserted leaps display as…23:59:60, matching referencezdump(the TAI wall rendering near leaps)
Acceptance (Phase 1 + 2 + 3, met)
Accepted when a Rust TZif witness can read selected TZif files (by path or named zone), evaluate
offset/is_dst/abbrev at instants, project footer-governed future instants without guessing, list
explicit transitions over a bounded -c lo,hi window, render right/ inserted leap seconds as
23:59:60, cross-check against reference zdump on pinned fixtures, and continue refusing full
zdump CLI/output parity.
tests/witness_golden.rs— pins witness + transition output to committed goldens forAmerica/New_York,Europe/London,UTC,America/Vancouver(the real 2026a→2026b release-diff zone), and theright/profiles (deterministic, no oracle); assertsright/UTCcarries the full monotonic leap table.tests/cross_check_zdump.rs— parses referencezdump -vand confirms zdump-rs agrees at probe instants including footer-projected far-future (2200) andright/zones (48/48), and that theright/UTCleap-second:60instants match zdump (27/27); auto-skips with a reason ifzdumpis absent.- unit: POSIX footer parsing (incl. southern-hemisphere wrap, angle-bracket numeric names), leap
:60rendering, named-zone resolution.
Pinned fixtures + their sha256 in fixtures/SHA256SUMS (the America/New_York fixture is byte-identical to the matrix's New_York, e9ed07d7…).
Explicit NON-claims (guarded as hard as the capability)
not a full zdump replacement not exact stdout/stderr parity not all flags
not locale behaviour not a replacement oracle not civil-time truth
Leap scope (honest): the inserted leap-second instants are rendered (…23:59:60, cross-checked vs
zdump); zdump-rs does not convert every arbitrary instant on the TAI scale to leap-aware wall time —
it surfaces offset/is_dst/abbreviation (leap-independent) + the leap table + the :60 instants.
Scope ladder
- Phase 1 (done): witness reader — read TZif, evaluate at instants, emit JSON, cross-check
zdump. - Phase 2 (done): transition listing over a window; footer-derived future projection; leap-table exposure.
- Phase 3 (done): partial
zdumpCLI compatibility — named zones ($TZDIR),-c lo,hi, andright/leap-second23:59:60rendering, all cross-checked against referencezdump. - Phase 4: full
zdumpreplacement — only if scope is explicitly expanded.
Zero dependencies; #![forbid(unsafe_code)]; overflow-checks in release.