From fb4894b444118fcdf57a74afa8db1e57c6db3b9e Mon Sep 17 00:00:00 2001 From: Darshil Patel Date: Fri, 18 Sep 2026 18:32:38 +0530 Subject: [PATCH] date: treat empty --file lines as midnight today like GNU Empty, whitespace-only, and lone "-" lines in --file/stdin input printed the current time instead of midnight. Normalize them to midnight, mirroring the existing -d handling. Fixes #14498. --- src/uu/date/src/date.rs | 24 +++++++++++++++++++++++- tests/by-util/test_date.rs | 13 +++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 455e72d6e09..0259b92fa77 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -1165,7 +1165,17 @@ fn parse_dates_from_reader( bytes.pop(); } match String::from_utf8(bytes) { - Ok(s) => parse_date(s, now, dbg_opts, allow_extended), + Ok(s) => { + let trimmed = s.trim(); + if trimmed.is_empty() || trimmed == "-" { + // GNU treats empty lines (and a lone "-", like `-d`) in + // `--file`/stdin input as midnight today, not the + // current time (issue #14498). + Ok(ParsedDateTime::InRange(midnight_today(now))) + } else { + parse_date(s, now, dbg_opts, allow_extended) + } + } // Report lines with invalid UTF-8 (with non-printable bytes // octal-escaped like GNU) instead of silently stopping the input Err(e) => Err(( @@ -1176,6 +1186,18 @@ fn parse_dates_from_reader( })) } +/// Midnight at the start of `now`'s civil date, in its time zone. +/// +/// Empty (whitespace-only or lone `-`) lines in `--file`/stdin input mean +/// midnight today for GNU `date`, mirroring the `-d` handling above. Falls +/// back to `now` itself on zones whose midnight does not exist. +fn midnight_today(now: &Zoned) -> Zoned { + now.date() + .at(0, 0, 0, 0) + .to_zoned(now.time_zone().clone()) + .unwrap_or_else(|_| now.clone()) +} + /// Parse a string into either an in-range [`Zoned`] value or an extended date. fn parse_date>( s: S, diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index 7f9e2c4eceb..a239e73a6f0 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -642,6 +642,19 @@ fn test_date_for_file() { ucmd.arg("--file").arg(file).succeeds(); } +#[test] +fn test_date_file_empty_lines_are_midnight() { + // Empty, whitespace-only, and lone `-` lines mean midnight today, + // like GNU, not the current time (#14498). + let (at, mut ucmd) = at_and_ucmd!(); + at.write("dates", "\n \n-\n"); + ucmd.arg("--file") + .arg("dates") + .arg("+%H:%M") + .succeeds() + .stdout_is("00:00\n00:00\n00:00\n"); +} + #[test] fn test_date_file_invalid_utf8_line() { let (at, mut ucmd) = at_and_ucmd!();