Skip to content

fix(time): show dates for files modified before the UNIX epoch#1826

Open
xfocus3 wants to merge 1 commit into
eza-community:mainfrom
xfocus3:fix/pre-epoch-file-time-1668
Open

fix(time): show dates for files modified before the UNIX epoch#1826
xfocus3 wants to merge 1 commit into
eza-community:mainfrom
xfocus3:fix/pre-epoch-file-time-1668

Conversation

@xfocus3

@xfocus3 xfocus3 commented May 31, 2026

Copy link
Copy Markdown

Problem

Files whose modification (or access/change) time is before the UNIX epoch (1970-01-01) render their date as - in eza, even though ls shows the correct date (e.g. 1901-12-13 ...). See #1668.

Root cause

File::systemtime_to_naivedatetime in src/fs/file.rs did:

let duration = st.duration_since(SystemTime::UNIX_EPOCH).ok()?;

SystemTime::duration_since returns Err whenever the time is earlier than the epoch, and .ok()? silently converted that Err into None. Every pre-epoch timestamp therefore became "no date", which the table renderer prints as -.

Fix

Handle the Err branch instead of discarding it:

  • On Ok(d): behave as before (positive seconds + nanos).
  • On Err(e): recover the absolute offset from e.duration(), negate the seconds, and when there is a sub-second part floor towards negative infinity (secs -= 1; nanos = 1_000_000_000 - nanos) so the value matches how Unix timestamps count time before 1970.

The timestamp is then built with chrono::DateTime::from_timestamp(secs, nanos), which already accepts negative seconds, keeping the existing Option<NaiveDateTime> return type and .naive_local() conversion. The change is localized to this one function. ls is treated as the ground-truth behavior.

Tests

Added a #[cfg(test)] mod systemtime_to_naivedatetime_test covering:

  • a normal post-epoch time (still works, year 2001),
  • the epoch itself (timestamp 0, year 1970),
  • a pre-epoch time (UNIX_EPOCH - 2_147_483_648s, year 1901, timestamp -2_147_483_648),
  • a pre-epoch time with a sub-second part (verifies the floor-towards-negative-infinity handling: -10.25s -> timestamp -11, nanos 750_000_000).

cargo build, cargo test fs::file, cargo clippy -- -D warnings, and cargo fmt --check all pass locally on the pinned toolchain (1.90).

Closes #1668

`systemtime_to_naivedatetime` called `duration_since(UNIX_EPOCH).ok()?`,
which returns `Err` for any timestamp before 1970 and was silently turned
into `None`. As a result eza rendered pre-epoch mtimes/atimes/ctimes as
`-` instead of a real date, while `ls` shows the correct date.

Handle the `Err` case by recovering the negative offset from
`err.duration()`, flooring towards negative infinity when there is a
sub-second component, and building the timestamp with
`DateTime::from_timestamp`, which accepts negative seconds. Add unit
tests covering pre-epoch, sub-second pre-epoch, the epoch, and a normal
post-epoch time.

Closes eza-community#1668
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.

bug: no time information for files before UNIX epoch

1 participant