Repository navigation
fix(offset): treat a numeric offset after a time of day as a zone correction #326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -876,4 +876,48 @@ mod tests { | |
| // duplicate check. GNU rejects it too. | ||
| assert!(parse(&mut "j +05:00").is_err()); | ||
| } | ||
|
|
||
| /// A numeric offset after a time of day is a time zone correction, even | ||
| /// when a relative item follows it. GNU `date` reads | ||
| /// `2026-08-27 12:00 +3 hours` as the zone `+03:00` plus a bare `hours` | ||
| /// (which means one hour), i.e. 10:00 UTC. | ||
| #[test] | ||
| fn numeric_offset_before_relative_item() { | ||
| for (expected, input) in [ | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00 +3 hours"), | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00 +3 hour"), | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00 +3hours"), | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00 + 3 hours"), | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00 +03 hours"), | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00 +0300 hours"), | ||
| ("2026-08-27 10:00:00", "2026-08-27 12:00:00 +3 hours"), | ||
| ("2026-08-27 10:05:00", "2026-08-27 12:00 +3 hours 5 minutes"), | ||
| ("2026-08-27 08:00:00", "2026-08-27 12:00 +3 hours ago"), | ||
| ("2026-08-28 09:00:00", "2026-08-27 12:00 +3 days"), | ||
| ("2026-08-27 09:01:00", "2026-08-27 12:00 +3 minutes"), | ||
| ("2026-08-27 16:00:00", "2026-08-27 12:00 -3 hours"), | ||
| ("2026-08-27 00:00:00", "2026-08-27 12:00 +13 hours"), | ||
| // A named zone already fills the zone slot, so the numeric value | ||
| // stays a relative item. | ||
| ("2026-08-27 15:00:00", "2026-08-27 12:00 utc +3 hours"), | ||
| // Without a time of day there is no zone slot to fill either. | ||
| ("2026-08-27 03:00:00", "2026-08-27 +3 hours"), | ||
| // A fractional number is never a zone correction. | ||
| ("2026-08-27 12:00:01", "2026-08-27 12:00 +1.5 seconds"), | ||
| ] { | ||
| let parsed = parse(&mut &*input) | ||
| .map(at_utc) | ||
| .expect("parsing failed during tests") | ||
| .with_time_zone(TimeZone::UTC); | ||
| assert_eq!( | ||
| expected, | ||
| parsed.strftime("%Y-%m-%d %H:%M:%S").to_string(), | ||
| "{input}" | ||
| ); | ||
| } | ||
|
|
||
| // `+30` is not a valid zone correction, and GNU rejects the whole | ||
| // input rather than falling back to a relative item. | ||
| assert!(parse(&mut "2026-08-27 12:00 +30 hours").is_err()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. out of range is a hard error now, so please check what
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's an error, like GNU's |
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add a few of these cases in tests/time.rs too, that's where we keep the gnu-compared expectations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added 12 cases to
tests/time.rs, expected values taken from GNU 9.11, plus+30 hoursintest_time_invalid. Also rebased onto main and squashed to one commit (62a9b02):time_zone_correctionis now separate fromtimezone_offset, which keeps its relative lookahead forUTC +8 years.