Skip to content
Merged
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
11 changes: 10 additions & 1 deletion benches/parse_datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,16 @@ fn bench_relative_keywords(c: &mut Criterion) {
}

fn bench_weekday(c: &mut Criterion) {
c.bench_function("parse_weekday", |b| b.iter(|| parse_datetime("wednesday")));
// Use a fixed reference date: the cost of resolving a weekday depends on
// how many days separate it from "today", so relying on the current date
// makes the measurement vary with the day the benchmark runs.
// 2000-01-03 is a Monday, so "wednesday" resolves two days ahead.
let base = jiff::civil::DateTime::from(jiff::civil::date(2000, 1, 3))
.to_zoned(jiff::tz::TimeZone::UTC)
.unwrap();
c.bench_function("parse_weekday", |b| {
b.iter(|| parse_datetime_at_date(base.clone(), "wednesday"))
});
}

fn bench_timezone_offset(c: &mut Criterion) {
Expand Down
16 changes: 11 additions & 5 deletions src/items/offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ fn timezone_name_to_offset(input: &str) -> ModalResult<Offset> {
"ut" => (false, 0, 0),
"u" => (true, 8, 0),
"t" => (true, 7, 0),
"sst" => (true, 11, 0),
"sst" => (true, 12, 0),
"sgt" => (false, 8, 0),
"sast" => (false, 2, 0),
"s" => (true, 6, 0),
Expand Down Expand Up @@ -329,7 +329,7 @@ fn timezone_name_to_offset(input: &str) -> ModalResult<Offset> {
"i" => (false, 9, 0),
"hst" => (true, 10, 0),
"h" => (false, 8, 0),
"gst" => (false, 4, 0),
"gst" => (false, 10, 0),
"gmt" => (false, 0, 0),
"g" => (false, 7, 0),
"f" => (false, 6, 0),
Expand All @@ -348,15 +348,15 @@ fn timezone_name_to_offset(input: &str) -> ModalResult<Offset> {
"cdt" => (true, 5, 0),
"cat" => (false, 2, 0),
"c" => (false, 3, 0),
"bst" => (false, 6, 0),
"bst" => (false, 1, 0),
"brt" => (true, 3, 0),
"brst" => (true, 2, 0),
"b" => (false, 2, 0),
"ast" => (true, 3, 0),
"ast" => (true, 4, 0),
"art" => (true, 3, 0),
"akst" => (true, 9, 0),
"akdt" => (true, 8, 0),
"adt" => (false, 4, 0),
"adt" => (true, 3, 0),
"a" => (false, 1, 0),
_ => return Err(ErrMode::Backtrack(ContextError::new())),
};
Expand Down Expand Up @@ -459,6 +459,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)), // 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