date: reject a trailing timezone when the input already has one - #14168
Open
ARMeeru wants to merge 1 commit into
Open
date: reject a trailing timezone when the input already has one#14168ARMeeru wants to merge 1 commit into
ARMeeru wants to merge 1 commit into
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
|
GNU testsuite comparison: |
Author
|
Reviewing the failures. |
`try_parse_with_abbreviation` strips a trailing timezone abbreviation and
re-parses what is left, which let it accept strings the parser had already
rejected. Its guard only caught a remaining bare abbreviation such as
"EST PST", so anything else carrying zone information slipped past it:
date -d "Jan 23 6:00PM GMT-1 EST" # an offset and a zone
date -d "023-060 MEST" # a time with an offset, and a zone
date -d "@0 EST" # a timestamp cannot take a zone
GNU date rejects all of these. We accepted them, and the "023-060" case
quietly answered with today's date.
Rather than reimplement the offset grammar here, read the answer off the
parse this path already performs. parse_datetime hands back the zone the
input named, or the current zone when it named none, so a mismatch says the
remainder carries its own. A leading "@" is tested directly, since a
timestamp cannot take a zone at all. The parser is consulted a second time
only when the remainder does name a zone whose offset coincides with the
current one, which the comparison cannot see on its own. The common case
stays at a single parse, and that matters because -f runs this once per line.
Input that carries zone information of its own, or cannot take one at all,
now falls through to the standard parser and is rejected.
The abbreviations this path exists for are unaffected, including the
Australian ones that GNU does not support. Checked against GNU coreutils
9.11 over the conflicting forms in several timezones, and over 300 inputs
GNU accepts, none of which this change rejects.
Closes uutils#13865
ARMeeru
force-pushed
the
fix/date-reject-conflicting-timezones
branch
from
August 27, 2026 07:32
04781ae to
9693b5d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #13865.
dateaccepted two inputs that GNU rejects:Root cause
It is not
parse_datetime. The crate rejects both strings, both at the pinned 0.15.0 and on its main branch. I checked by calling it directly rather than throughdate.try_parse_with_abbreviationstrips a trailing timezone abbreviation and re-parses what is left, so that the abbreviation can be applied as the input timezone. It already guarded against a second timezone, but only by checking whether the last remaining word was itself a bare abbreviation. That catchesEST PSTand nothing else.GMT-1fails the shape check because of the hyphen and023-060fails it because of the digits, so both were rescued after the standard parser had correctly rejected them. In the second case023-060parses on its own as 23:00 with a -01:00 offset, which is where the surprising today's-date output came from.The same hole let
@0 ESTthrough, and a timestamp cannot take a timezone at all.The change
Ask
parse_datetimewhether what is left can still take a timezone, by appending one it already understands. If it cannot, the remainder either carries timezone information of its own or cannot accept one, so the rescue is declined and the whole string falls through to the standard parser, which rejects it.This keeps the offset grammar in one place. The alternative was to recognise offset forms textually in
date.rs, which means maintaining a second copy of that grammar, and a rule broad enough to catch023-060also matches the-15in2024-01-15.Deleting this rescue path was the other option, and it does not work:
parse_datetime0.15.0 rejectsMEZ,MESZ,MESTandKST, which GNU accepts, and it rejects the Australian abbreviations thattests/by-util/test_date.rsdeliberately covers. All of those still parse.Tests
test_date_rejects_input_that_cannot_take_a_timezonecovers the two inputs from the issue plus2024-01-15 12:00 EST ESTand@0 EST.test_date_accepts_gnu_timezone_abbreviationspins the abbreviations that must keep working, including the four that only this path handles. The first one fails before the change. The second passes before and after, and is there to catch a regression.Verification
Differential testing against GNU coreutils 9.1 over 66 inputs, comparing this branch, its base commit, and GNU. There is no input where this branch disagrees with GNU while the base agreed. Everything that changed moved from accepted to rejected, matching GNU each time, and that includes
2024-01-15T12:00Z EST, which is not one of the reported cases.The date suite goes from 142 to 144 passing with the same five failures before and after. Those five are
test_date_set_valid*andtest_date_for_no_permission_file, which fail in my container because setting the clock needs a capability it does not have.cargo fmt --checkandcargo clippy --all-targets -- -D warningsare clean.Every GNU behaviour referenced here was measured by running GNU
date, not by reading its source.Left alone
Three things I noticed while working on this, all separate from the reported bug and none of them touched here:
date -d '2024-01-15 12:00 OSLO'works.build_tz_abbrev_mapderives them from zone-name suffixes. GNU rejects them.parse_datetimereturns offsets that differ from GNU forADT,AST,BST,GSTandSST. Wrong times rather than errors, and the ambiguity looks like a decision for maintainers.TZ="EST5EDT" 2024-06-01 12:00gives 16:00 under GNU and fails here.TZ="America/New_York"works, so it is specific to that form.Happy to file these separately if they are worth tracking.