Skip to content

fix(ls): render actual UTC calendar dates in long format#2144

Merged
chaliy merged 1 commit into
everruns:mainfrom
a0preetham:fix-ls-date-format
Jul 6, 2026
Merged

fix(ls): render actual UTC calendar dates in long format#2144
chaliy merged 1 commit into
everruns:mainfrom
a0preetham:fix-ls-date-format

Conversation

@a0preetham

Copy link
Copy Markdown
Contributor

Problem

ls -l computes its date column with hand-rolled "approximate" calendar math:

let years = 1970 + (days / 365);      // no leap years
let remaining_days = days % 365;
let month = remaining_days / 30 + 1;  // 30-day months
let day = remaining_days % 30 + 1;

The error compounds ~1 day per 4 years (14 leap days since 1972) plus up to ±5 days within a year from the 30-day-month approximation. Today the drift is 15 days: a file touched on 2026-07-05 lists as 2026-07-20. Late-December dates overshoot into the next year entirely (2026-12-31 renders as 2027-01-14), and leap days are unrepresentable.

Found while verifying the wasm browser build from #2141ls -la disagreed with date in the same session. Reproduces identically on native; it's not wasm-related.

Fix

Replace the arithmetic with chrono via time_compat::to_chrono_utc — the same conversion the date builtin already uses for file mtimes — keeping the existing long-iso output style (YYYY-MM-DD HH:MM, UTC). The ????-??-?? ??:?? pre-epoch fallback branch is gone too: to_chrono_utc handles pre-epoch times correctly since #2140.

Tests

Written first and confirmed failing against the old code. They pin exact rendering using InMemoryFs::set_modified_time with fixed epoch seconds (timezone-independent):

  • mid-year date: 2026-07-05 20:05 (old code: 2026-07-20)
  • leap day: 2024-02-29 12:00 (old code: 2024-03-13)
  • year boundary: 2026-12-31 23:59 (old code: 2027-01-14)

Verification

  • all 82 ls unit tests pass; workspace --lib --bins suite passes (3,351 tests)
  • time_compat source-scan test passes
  • fmt + clippy -D warnings clean
  • e2e via bashkit-cli: touch /tmp/f && ls -la /tmp && date -u — ls and date now agree

ls -l computed the date column with hand-rolled "approximate" math: no
leap years (1970 + days/365) and 30-day months (remaining/30 + 1). The
error compounds ~1 day per 4 years plus up to ±5 days within a year —
by 2026 a July 5 mtime rendered as 2026-07-20, and late-December dates
overshot into the next year entirely (2026-12-31 -> 2027-01-14).

Replace the arithmetic with chrono via time_compat::to_chrono_utc, the
same conversion the date builtin already uses, keeping the long-iso
output style (YYYY-MM-DD HH:MM). Tests pin exact rendering for a
mid-year date, a leap day (2024-02-29, unrepresentable under the old
math), and a year boundary.
@chaliy chaliy merged commit a18ad22 into everruns:main Jul 6, 2026
31 checks passed
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.

3 participants