diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index c305e2548..f4c9313cb 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -274,13 +274,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { match date { Ok(date) => { let format_string = custom_time_format(format_string); - // Refuse to pass this string to chrono as it is crashing in this crate - if format_string.contains("%#z") { - return Err(USimpleError::new( - 1, - format!("invalid format {}", format_string.replace("%f", "%N")), - )); - } // Hack to work around panic in chrono, // TODO - remove when a fix for https://github.com/chronotope/chrono/issues/623 is released let format_items = StrftimeItems::new(format_string.as_str()); diff --git a/src/uucore/src/lib/features/custom_tz_fmt.rs b/src/uucore/src/lib/features/custom_tz_fmt.rs index 132155f54..0d2b6aebe 100644 --- a/src/uucore/src/lib/features/custom_tz_fmt.rs +++ b/src/uucore/src/lib/features/custom_tz_fmt.rs @@ -35,8 +35,10 @@ fn timezone_abbreviation() -> String { /// A string that can be used as parameter of the chrono functions that use formats pub fn custom_time_format(fmt: &str) -> String { // TODO - Revisit when chrono 0.5 is released. https://github.com/chronotope/chrono/issues/970 + // chrono crashes on %#z, but it's the same as %z anyway. // GNU `date` uses `%N` for nano seconds, however the `chrono` crate uses `%f`. - fmt.replace("%N", "%f") + fmt.replace("%#z", "%z") + .replace("%N", "%f") .replace("%Z", timezone_abbreviation().as_ref()) } diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index bb94ec020..9371a9477 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -169,6 +169,14 @@ fn test_date_format_y() { scene.ucmd().arg("+%y").succeeds().stdout_matches(&re); } +#[test] +fn test_date_format_q() { + let scene = TestScenario::new(util_name!()); + + let re = Regex::new(r"^[1-4]\n$").unwrap(); + scene.ucmd().arg("+%q").succeeds().stdout_matches(&re); +} + #[test] fn test_date_format_m() { let scene = TestScenario::new(util_name!()); @@ -381,10 +389,12 @@ fn test_invalid_format_string() { } #[test] -fn test_unsupported_format() { - let result = new_ucmd!().arg("+%#z").fails(); - result.no_stdout(); - assert!(result.stderr_str().starts_with("date: invalid format %#z")); +fn test_capitalized_numeric_time_zone() { + // %z +hhmm numeric time zone (e.g., -0400) + // # is supposed to capitalize, which makes little sense here, but chrono crashes + // on such format so it's good to test. + let re = Regex::new(r"^[+-]\d{4,4}\n$").unwrap(); + new_ucmd!().arg("+%#z").succeeds().stdout_matches(&re); } #[test]