From b818481e5f2cbfdb3df4bac715a81dcc63085ea7 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 26 Oct 2025 20:47:13 +0100 Subject: [PATCH] date: fix parse_datetime 0.13 API compatibility issues --- Cargo.lock | 6 +++--- fuzz/Cargo.lock | 7 +++---- src/uu/date/src/date.rs | 35 ++++++++++++++++++++++------------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 833f11516..8a1579edc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -508,7 +508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1074,7 +1074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1667,7 +1667,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index b7c7e85cf..1f8eeab9f 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -1071,13 +1071,12 @@ checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" [[package]] name = "parse_datetime" -version = "0.11.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b77d27257a460cefd73a54448e5f3fd4db224150baf6ca3e02eedf4eb2b3e9" +checksum = "77d45119ed61100f40b2389d8ed12e51ec869046d4279afbb5a7c73a4733be36" dependencies = [ - "chrono", + "jiff", "num-traits", - "regex", "winnow", ] diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index e101c1c97..d38905988 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -459,8 +459,9 @@ fn make_format_string(settings: &Settings) -> &str { /// - MST: Mountain Standard Time (US) preferred over Malaysia Standard Time /// - PST: Pacific Standard Time (US) - widely used abbreviation /// - GMT: Alias for UTC (universal) +/// - Australian timezones: AWST, ACST, AEST (cannot be dynamically discovered) /// -/// All other timezones (AWST, JST, CET, etc.) are dynamically resolved from IANA database. // spell-checker:disable-line +/// All other timezones (JST, CET, etc.) are dynamically resolved from IANA database. // spell-checker:disable-line static PREFERRED_TZ_MAPPINGS: &[(&str, &str)] = &[ // Universal (no ambiguity, but commonly used) ("UTC", "UTC"), @@ -476,6 +477,12 @@ static PREFERRED_TZ_MAPPINGS: &[(&str, &str)] = &[ ("EDT", "America/New_York"), // Other highly ambiguous cases ("IST", "Asia/Kolkata"), // Ambiguous: India vs Israel vs Ireland // spell-checker:disable-line + // Australian timezones (cannot be discovered from IANA location names) + ("AWST", "Australia/Perth"), // Australian Western Standard Time + ("ACST", "Australia/Adelaide"), // Australian Central Standard Time + ("ACDT", "Australia/Adelaide"), // Australian Central Daylight Time + ("AEST", "Australia/Sydney"), // Australian Eastern Standard Time + ("AEDT", "Australia/Sydney"), // Australian Eastern Daylight Time ]; /// Lazy-loaded timezone abbreviation lookup map built from IANA database. @@ -547,18 +554,15 @@ fn resolve_tz_abbreviation>(date_str: S) -> String { // Try to parse the date with UTC first to get timestamp let date_with_utc = format!("{date_part} +00:00"); if let Ok(parsed) = parse_datetime::parse_datetime(&date_with_utc) { - // Create timestamp from parsed date - if let Ok(ts) = Timestamp::new( - parsed.timestamp(), - parsed.timestamp_subsec_nanos() as i32, - ) { - // Get the offset for this specific timestamp in the target timezone - let zoned = ts.to_zoned(tz); - let offset_str = format!("{}", zoned.offset()); + // Get timestamp from parsed date (which is already a Zoned) + let ts = parsed.timestamp(); - // Replace abbreviation with offset - return format!("{date_part} {offset_str}"); - } + // Get the offset for this specific timestamp in the target timezone + let zoned = ts.to_zoned(tz); + let offset_str = format!("{}", zoned.offset()); + + // Replace abbreviation with offset + return format!("{date_part} {offset_str}"); } } } @@ -585,7 +589,12 @@ fn parse_date + Clone>( let resolved = resolve_tz_abbreviation(s.as_ref()); match parse_datetime::parse_datetime(&resolved) { - Ok(date) => Ok(date), + Ok(date) => { + // Convert to system timezone for display + // (parse_datetime 0.13 returns Zoned in the input's timezone) + let timestamp = date.timestamp(); + Ok(timestamp.to_zoned(TimeZone::try_system().unwrap_or(TimeZone::UTC))) + } Err(e) => Err((s.as_ref().into(), e)), } }