mirror of
https://github.com/storytold/craft-launcher.git
synced 2026-10-22 18:22:10 +00:00
`civil_from_unix` (core) and `rfc3339` (xtask) took `i64` Unix seconds, which the old hand-rolled Hinnant code converted across the whole `i64` range. The jiff rewrite built the date with `epoch.checked_add(whole_days).unwrap_or(epoch)`, but jiff's civil calendar only spans years -9999..=9999 — far narrower than chrono's — so any instant past year 9999 silently became the epoch, changing existing output. `i64::MAX` used to read `Dec 4, 292277026596` / `292277026596-12-04T15:30:07Z`, and `i64::MIN` `Jan 27, -292277022657`, not 1970. Fix: move the instant into jiff's range by whole 400-year Gregorian cycles (146_097 days) before converting, then restore the real year afterwards. `rest` is always under one cycle, so the in-range date lands in 1970..=2369 (well inside jiff) and `rest * 86_400` can't overflow; the year is restored through `i128` so `cycles * 400` is exact at the `i64` extremes. jiff stays the only calendar logic (it does the month/day); the cycle count just shifts the year. No epoch fallback for any value the old code converted. core still builds for wasm32. Tests now pin the old output instead of the epoch: - core civil_from_unix(i64::MAX) == (292277026596, 12, 4), civil_from_unix(i64::MIN) == (-292277022657, 1, 27), civil_from_unix(253_402_300_800) == (10000, 1, 1) - xtask rfc3339(i64::MAX) == "292277026596-12-04T15:30:07Z", rfc3339(i64::MIN) == "-292277022657-01-27T08:29:52Z", rfc3339(253_402_300_800) == "10000-01-01T00:00:00Z"