Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/items/offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ fn timezone_name_to_offset(input: &str) -> ModalResult<Offset> {
"ut" => Ok("+0"),
"u" => Ok("-8"),
"t" => Ok("-7"),
"sst" => Ok("-11"),
"sst" => Ok("-12"),
"sgt" => Ok("+8"),
"sast" => Ok("+2"),
"s" => Ok("-6"),
Expand Down Expand Up @@ -331,7 +331,7 @@ fn timezone_name_to_offset(input: &str) -> ModalResult<Offset> {
"i" => Ok("+9"),
"hst" => Ok("-10"),
"h" => Ok("+8"),
"gst" => Ok("+4"),
"gst" => Ok("+10"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gst +10 is Guam, but most people writing GST mean Gulf time (+4, Dubai), which is what we had. could you please explain why Guam wins here? it silently changes what users get today.

@ARMeeru ARMeeru Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guam wins because it's the value GNU's own zone table assigns this token: GST is Guam Standard Time there, and date --debug -d "2026-06-15 12:00 GST" on GNU coreutils 9.10 reports parsed zone part: UTC+10. I take the point that most people writing GST mean Dubai, and this does silently change what they get today. The crate's documented scope is "we support the same subset as GNU date", so I went with GNU's reading. If you'd rather match common usage than GNU here, I'll put +4 back.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't quote GNU :(
the licenses are incompatible ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about that :( you're right. I copied the table lines into two of the replies without thinking about the license side, and that was the wrong way to present the evidence. I've replaced them with the offsets stated plainly. The date --debug output is still there, and nothing quoted remains.

"gmt" => Ok("+0"),
"g" => Ok("+7"),
"f" => Ok("+6"),
Expand All @@ -350,15 +350,15 @@ fn timezone_name_to_offset(input: &str) -> ModalResult<Offset> {
"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())),
}?;
Expand Down Expand Up @@ -457,6 +457,12 @@ mod tests {
("mesz", off(false, 2, 0)),
("mest", off(false, 2, 0)),
("kst", off(false, 9, 0)),
// Corrected to the offsets GNU date assigns these abbreviations.
("adt", off(true, 3, 0)), // Atlantic Daylight, was +4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please also add a test in tests/ going through parse_datetime, like "2026-06-15 12:00 BST"? that's the actual user-facing bug.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done. Added the tests in tests/date.rs; they go through parse_datetime and cover all five abbreviations.

("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, 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;
Expand Down
13 changes: 13 additions & 0 deletions tests/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 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")]
#[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,
Expand Down
Loading