From d71e381091b3893148d3ac12406eacbc33f1debc Mon Sep 17 00:00:00 2001 From: Asifur Rahaman Meeru Date: Fri, 28 Aug 2026 09:47:17 +0600 Subject: [PATCH 1/3] fix(offset): correct ADT, AST, BST and GST to GNU's values --- src/items/offset.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/items/offset.rs b/src/items/offset.rs index 5ccdc10..a243d27 100644 --- a/src/items/offset.rs +++ b/src/items/offset.rs @@ -331,7 +331,7 @@ fn timezone_name_to_offset(input: &str) -> ModalResult { "i" => Ok("+9"), "hst" => Ok("-10"), "h" => Ok("+8"), - "gst" => Ok("+4"), + "gst" => Ok("+10"), "gmt" => Ok("+0"), "g" => Ok("+7"), "f" => Ok("+6"), @@ -350,15 +350,15 @@ fn timezone_name_to_offset(input: &str) -> ModalResult { "cdt" => Ok("-5"), "cat" => Ok("+2"), "c" => Ok("+3"), - "bst" => Ok("+6"), + "bst" => Ok("+1"), "brt" => Ok("-3"), "brst" => Ok("-2"), "b" => Ok("+2"), - "ast" => Ok("-3"), + "ast" => Ok("-4"), "art" => Ok("-3"), "akst" => Ok("-9"), "akdt" => Ok("-8"), - "adt" => Ok("+4"), + "adt" => Ok("-3"), "a" => Ok("+1"), _ => Err(ErrMode::Backtrack(ContextError::new())), }?; @@ -457,6 +457,14 @@ mod tests { ("mesz", off(false, 2, 0)), ("mest", off(false, 2, 0)), ("kst", off(false, 9, 0)), + // Each of these resolved to a different real meaning of the + // abbreviation than the one GNU date uses, e.g. BST as Bangladesh + // Standard Time rather than British Summer Time. + ("adt", off(true, 3, 0)), // Atlantic Daylight, was +4 + ("ast", off(true, 4, 0)), // Atlantic Standard, was -3 + ("bst", off(false, 1, 0)), // British Summer, was +6 + ("gst", off(false, 10, 0)), // Guam Standard, was +4 + ("sst", off(true, 11, 0)), ("z123", off(false, 0, 0)), // space separator can be ignored if immediately followed by digits (GNU date behavior) ] { let mut s = input; From 258ab904a7c21da21c352a475b431dfcfcae7cb8 Mon Sep 17 00:00:00 2001 From: Asifur Rahaman Meeru Date: Tue, 22 Sep 2026 17:01:30 +0600 Subject: [PATCH 2/3] fix(offset): correct SST to GNU's -12 value --- src/items/offset.rs | 8 +++----- tests/date.rs | 13 +++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/items/offset.rs b/src/items/offset.rs index a243d27..4cec491 100644 --- a/src/items/offset.rs +++ b/src/items/offset.rs @@ -300,7 +300,7 @@ fn timezone_name_to_offset(input: &str) -> ModalResult { "ut" => Ok("+0"), "u" => Ok("-8"), "t" => Ok("-7"), - "sst" => Ok("-11"), + "sst" => Ok("-12"), "sgt" => Ok("+8"), "sast" => Ok("+2"), "s" => Ok("-6"), @@ -457,14 +457,12 @@ mod tests { ("mesz", off(false, 2, 0)), ("mest", off(false, 2, 0)), ("kst", off(false, 9, 0)), - // Each of these resolved to a different real meaning of the - // abbreviation than the one GNU date uses, e.g. BST as Bangladesh - // Standard Time rather than British Summer Time. + // Corrected to the offsets of GNU date's zone table (gnulib parse-datetime.y). ("adt", off(true, 3, 0)), // Atlantic Daylight, was +4 ("ast", off(true, 4, 0)), // Atlantic Standard, was -3 ("bst", off(false, 1, 0)), // British Summer, was +6 ("gst", off(false, 10, 0)), // Guam Standard, was +4 - ("sst", off(true, 11, 0)), + ("sst", off(true, 12, 0)), // Samoa Standard, was -11 ("z123", off(false, 0, 0)), // space separator can be ignored if immediately followed by digits (GNU date behavior) ] { let mut s = input; diff --git a/tests/date.rs b/tests/date.rs index e410051..44f4584 100644 --- a/tests/date.rs +++ b/tests/date.rs @@ -298,6 +298,19 @@ fn test_embedded_timezone(#[case] input: &str, #[case] expected: &str) { check_absolute(input, expected); } +// Zone abbreviations must resolve to the offsets of GNU date's zone table +// (gnulib parse-datetime.y), not to other real meanings of the same letters, +// e.g. BST as Bangladesh Standard Time rather than British Summer Time. +#[rstest] +#[case::bst("2026-06-15 12:00 BST", "2026-06-15 12:00:00+01:00")] +#[case::gst("2026-06-15 12:00 GST", "2026-06-15 12:00:00+10:00")] +#[case::ast("2026-06-15 12:00 AST", "2026-06-15 12:00:00-04:00")] +#[case::adt("2026-06-15 12:00 ADT", "2026-06-15 12:00:00-03:00")] +#[case::sst("2026-06-15 12:00 SST", "2026-06-15 12:00:00-12:00")] +fn test_zone_abbreviation_offsets(#[case] input: &str, #[case] expected: &str) { + check_absolute(input, expected); +} + // Regression test for uutils/coreutils#12555. // A fixed offset (e.g. the "UTC" keyword) must anchor the instant *before* // relative adjustments are applied. Otherwise, when the base zone observes DST, From 45f04c87f5f6f13cf9b8bc9ed442139dbf15a550 Mon Sep 17 00:00:00 2001 From: Asifur Rahaman Meeru Date: Tue, 22 Sep 2026 18:22:28 +0600 Subject: [PATCH 3/3] docs: reword the zone table comments --- src/items/offset.rs | 2 +- tests/date.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/items/offset.rs b/src/items/offset.rs index 4cec491..4bcde4d 100644 --- a/src/items/offset.rs +++ b/src/items/offset.rs @@ -457,7 +457,7 @@ mod tests { ("mesz", off(false, 2, 0)), ("mest", off(false, 2, 0)), ("kst", off(false, 9, 0)), - // Corrected to the offsets of GNU date's zone table (gnulib parse-datetime.y). + // Corrected to the offsets GNU date assigns these abbreviations. ("adt", off(true, 3, 0)), // Atlantic Daylight, was +4 ("ast", off(true, 4, 0)), // Atlantic Standard, was -3 ("bst", off(false, 1, 0)), // British Summer, was +6 diff --git a/tests/date.rs b/tests/date.rs index 44f4584..69756b3 100644 --- a/tests/date.rs +++ b/tests/date.rs @@ -298,9 +298,9 @@ fn test_embedded_timezone(#[case] input: &str, #[case] expected: &str) { check_absolute(input, expected); } -// Zone abbreviations must resolve to the offsets of GNU date's zone table -// (gnulib parse-datetime.y), not to other real meanings of the same letters, -// e.g. BST as Bangladesh Standard Time rather than British Summer Time. +// Zone abbreviations must resolve to the offsets GNU date assigns them, +// not to other real meanings of the same letters, e.g. BST as Bangladesh +// Standard Time rather than British Summer Time. #[rstest] #[case::bst("2026-06-15 12:00 BST", "2026-06-15 12:00:00+01:00")] #[case::gst("2026-06-15 12:00 GST", "2026-06-15 12:00:00+10:00")]