fix(offset): support the military timezone letter j (local time) - #320
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #320 +/- ##
=======================================
Coverage 99.33% 99.34%
=======================================
Files 21 21
Lines 4075 4125 +50
Branches 129 136 +7
=======================================
+ Hits 4048 4098 +50
Misses 26 26
Partials 1 1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
0xSoftBoi
force-pushed
the
fix/military-timezone-j
branch
from
August 25, 2026 05:10
d2cd43c to
87a29cf
Compare
GNU `date` accepts every letter `a`-`y` as a military time zone, and all
of them are already in our table except `j`. It is missing because it is
the one letter that does not denote a fixed offset: `j` means *local
time*, so it cannot be expressed as an `Offset` at all.
$ TZ=America/New_York date -d '8j' # 08:00 -0400
$ TZ=America/New_York date -d '2026-01-01 j' # 00:00 -0500
$ TZ=America/New_York date -d '8z' # 04:00 -0400
Because it follows the base zone's DST rules rather than pinning an
offset, it is represented as its own item and recorded on the builder as
a flag rather than as an offset.
- `j` parses as its own item, so `8j`, `8 j`, `j 8` and `8J` all work.
- It is still a time zone item, so `8j utc`, `8 utc j` and `8 j j` are
rejected as a repeated zone, matching GNU.
- The whole alphabetic word is consumed before comparing, so `8jan` still
parses as a date and `jj` is rejected rather than matching a `j` prefix.
- Unknown words remain errors: `8foo` still fails, as it does in GNU.
Verified against GNU coreutils 9.4: all 26 letters `a`-`z` now resolve to
the same instant as GNU, in both a DST and a non-DST base zone.
sylvestre
force-pushed
the
fix/military-timezone-j
branch
from
August 28, 2026 15:03
87a29cf to
180746e
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.
GNU
dateaccepts every lettera–yas a military time zone. All of them are already in our table except one:j.It is missing for a reason.
jis the single letter that does not denote a fixed offset — it means local time, so it cannot be expressed as anOffsetat all.What GNU actually does
Verified against GNU coreutils 9.4, in
TZ=America/New_York(EDT, UTC−4):8a08:00 +01:008n08:00 −01:008z04:00 −04008j08:00 −040082026-01-01 j00:00 −05008fooThe
2026-01-01 jrow is the important one: it resolves to −05:00 in January and −04:00 in August. It follows the zone's DST rules, so no fixed offset can represent it.The change
jis parsed as its own item and recorded on the builder as a flag rather than as an offset, so the local rule zone is used instead of a fixed one.8j,8 j,j 8and8Jall work.8j utc,8 utc jand8 j jare rejected as a repeated zone, matching GNU.8janstill parses as a date andjjis rejected rather than matching ajprefix.8foostill fails, as it does in GNU.Verification
I compared every letter
a–zagainst GNU coreutils 9.4, comparing resolved Unix timestamps in a DST zone:All 26 letters now resolve to the same instant as GNU. 403 tests pass, fmt and clippy clean.
Relationship to #286
This supersedes #286, and confirms @sylvestre's review there was correct.
#286 assumed GNU silently discards unrecognized trailing alphabetic tokens after a number. It does not —
date -d '8foo'is an invalid date. The only such token GNU actually accepts isj, and for a reason #286 did not model: it is a time zone, not noise to be skipped.#286 has also drifted five months behind
mainand its diff would revert several later fixes, so this is a fresh branch from currentmainrather than an update to it.