Skip to content

date: drop the E modifier in the C locale - #15237

Open
yu2971512385-ui wants to merge 1 commit into
uutils:mainfrom
yu2971512385-ui:date-e-modifier
Open

yu2971512385-ui wants to merge 1 commit into
uutils:mainfrom
yu2971512385-ui:date-e-modifier

Conversation

@yu2971512385-ui

Copy link
Copy Markdown

date +%Ey printed %Ey instead of the year. The six conversions POSIX pairs
the E modifier with (%Ec %EC %Ex %EX %Ey %EY) all went through to jiff,
which does not know the modifier and emits it literally.

In the C locale there is no era representation, so E falls back to the plain
conversion — the same rule %O already follows since #11656. strip_o_modifier
only looked for O, so it now looks for both and is renamed accordingly. E is
dropped only before c, C, x, X, y and Y, because GNU leaves the
other letters literal; a dangling %E, %E9 or an E behind %% stays
literal as before, and %O handling is unchanged.

Checked against GNU coreutils 9.x with LC_ALL=C TZ=UTC:

format before after / GNU
%Ey %Ey 09
%EY %EY 2009
%EC %EC 20
%Ex %Ex 02/13/09
%EX %EX 23:31:30
%Ec %Ec Fri Feb 13 23:31:30 2009
%Ej, %E, %E9, %%Ey literal literal

Part of #10958. It does not close it: that issue also asks for the ICU-backed
alternative representations, which #10994 is about — this only completes the
C-locale fallback that %O already had.

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)

Comment thread src/uu/date/src/date.rs Outdated
}
match chars.peek() {
Some('O') => {
Some(&modifier @ ('O' | 'E')) => {

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.

what happens with a flag or width before the modifier, like %-Ey or %10EY? please add a test

.env("TZ", "UTC")
.arg("-d")
.arg("2024-06-15")
.arg("+%Ey-%EY-%EC")

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 also cover %Ec, %Ex and %EX, they are in the list but not tested

%Ey and the other five conversions POSIX pairs the E modifier with were
passed through to jiff, which does not know the modifier and printed them
literally: `date -d @1234567890 +%Ey` gave `%Ey` where GNU gives `09`.

The C locale has no era representation, so the modifier falls back to the
plain conversion, exactly as %O already does. strip_o_modifier handled
only O, so it now handles both and is renamed to match. E is dropped only
before c, C, x, X, y and Y, since GNU keeps the others literal, and a
dangling %E or one behind %% stays literal as before.

Both modifiers sit behind the GNU flags and field width, as in `%-Oy` or
`%10EY`, so those are now skipped while looking for the modifier. That
also fixes %O, which printed `%Oy` for `%-Oy` and `00000000%OY` for
`%10OY`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@yu2971512385-ui

Copy link
Copy Markdown
Author

Thanks for the review. Written with AI assistance on my behalf, as with the PR itself; the measurements below are from GNU coreutils 9.x and this branch on macOS 15.

Both cases were already broken for %O on main, not just for %E:

main:  %-Oy -> %Oy          %10OY -> 00000000%OY
GNU:   %-Oy -> 9            %10OY -> 0000002009

The modifier scan started at % and so never got past the flags and width. It now skips them, which makes the %O side match GNU exactly:

%-Oy|%10OY|%_Om|%0Oy|%-Od   GNU and this branch: 24|0000002024| 6|24|15
%12Ex|%0EY                  GNU and this branch:     06/15/24|2024

Added as test_date_strftime_modifier_after_flags_and_width, and %Ec, %Ex, %EX are now covered in test_date_strftime_e_modifier.

Three cases still differ, and I did not want to guess at them:

          GNU            this branch
%-Ey      24             24
%_Ey      24              24
%10EY           2024     0000002024

GNU renders an E-modified year as an era string, so it pads with spaces and - does not suppress padding, while this branch applies the flags to the plain conversion it falls back to. I left that alone and recorded it as an ignored test (test_date_strftime_e_modifier_pads_like_a_string) rather than assert behaviour that does not match GNU. Happy to take it on in this PR if you would rather it were complete.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants