Skip to content

date: re-zone trailing TZ abbreviation input to local timezone#12327

Merged
sylvestre merged 1 commit into
uutils:mainfrom
0xSoftBoi:fix/281-trailing-tz-abbrev-rezones
May 16, 2026
Merged

date: re-zone trailing TZ abbreviation input to local timezone#12327
sylvestre merged 1 commit into
uutils:mainfrom
0xSoftBoi:fix/281-trailing-tz-abbrev-rezones

Conversation

@0xSoftBoi
Copy link
Copy Markdown
Contributor

Summary

try_parse_with_abbreviation in src/uu/date/src/date.rs returned a Zoned in the input abbreviation timezone (e.g. -05 for EST). The generic parse_datetime fallback already re-zones to now.time_zone() for display, so identical inputs took two divergent paths and only one matched GNU date.

GNU treats a trailing TZ abbreviation as describing the input timezone; the output is always re-zoned into the local zone (or UTC under -u). Under TZ=UTC:

$ /usr/bin/date -d "2024-01-01 EST"
Mon Jan  1 05:00:00 UTC 2024

# uutils before this PR
$ TZ=UTC target/debug/date -d "2024-01-01 EST"
Mon Jan  1 00:00:00 -05 2024

# uutils after this PR
$ TZ=UTC target/debug/date -d "2024-01-01 EST"
Mon Jan  1 05:00:00 UTC 2024

What changed

The abbreviation-aware path now does the same with_time_zone(now.time_zone().clone()) re-zoning the generic fallback already does. -u still produces UTC output because now is zoned to UTC in that case (date.rs:362), and the final output stage still applies with_time_zone(TimeZone::UTC) when settings.utc is set, so the existing -u + abbreviation tests (test_date_utc_with_d_flag, test_date_tz_abbreviation_fixed_offset_outside_season) are unchanged.

Testing

tests/by-util/test_date.rs already contained an #[ignore]d regression test for this issue; this PR un-ignores it. Full uu_date test suite is green locally:

test result: ok. 130 passed; 0 failed; 8 ignored; 0 measured; ...

Fixes uutils/parse_datetime#281.

The dedicated abbreviation-aware path `try_parse_with_abbreviation` in
`src/uu/date/src/date.rs` returned a `Zoned` in the input abbreviation
timezone (e.g. `-05` for `EST`). The generic `parse_datetime` fallback
already re-zones to `now.time_zone()` for display, so identical inputs
took two divergent code paths and only one matched GNU `date`.

GNU treats a trailing TZ abbreviation as describing the *input*
timezone; the output is always re-zoned into the local zone (or UTC
under `-u`). For example, under `TZ=UTC`:

    $ date -d "2024-01-01 EST"        # GNU
    Mon Jan  1 05:00:00 UTC 2024

uutils previously emitted `Mon Jan  1 00:00:00 -05 2024`.

Convert the parsed instant to `now.time_zone()` before returning,
matching the fallback path and GNU’s behavior. `-u` still works
because `now` is already zoned to UTC in that case (date.rs:362),
and the final output stage still applies `with_time_zone(TimeZone::UTC)`
when `settings.utc` is set.

Un-ignores the existing regression test for this issue.

Fixes uutils/parse_datetime#281.
@github-actions
Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/retry (passes in this run but fails in the 'main' branch)
Skip an intermittent issue tests/pr/bounded-memory (was skipped on 'main', now failing)

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 16, 2026

Merging this PR will improve performance by 13.71%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 315 untouched benchmarks
⏩ 46 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation ls_recursive_balanced_tree[(6, 4, 15)] 50.9 ms 48.9 ms +4.01%
Memory cp_recursive_deep_tree[(120, 4)] 699.2 KB 562.5 KB +24.31%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing 0xSoftBoi:fix/281-trailing-tz-abbrev-rezones (3783654) with main (d09f351)

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@sylvestre
Copy link
Copy Markdown
Contributor

nice, thanks

@sylvestre sylvestre merged commit dfd6297 into uutils:main May 16, 2026
171 checks passed
nonontb pushed a commit to nonontb/coreutils that referenced this pull request May 28, 2026
…s#12327)

The dedicated abbreviation-aware path `try_parse_with_abbreviation` in
`src/uu/date/src/date.rs` returned a `Zoned` in the input abbreviation
timezone (e.g. `-05` for `EST`). The generic `parse_datetime` fallback
already re-zones to `now.time_zone()` for display, so identical inputs
took two divergent code paths and only one matched GNU `date`.

GNU treats a trailing TZ abbreviation as describing the *input*
timezone; the output is always re-zoned into the local zone (or UTC
under `-u`). For example, under `TZ=UTC`:

    $ date -d "2024-01-01 EST"        # GNU
    Mon Jan  1 05:00:00 UTC 2024

uutils previously emitted `Mon Jan  1 00:00:00 -05 2024`.

Convert the parsed instant to `now.time_zone()` before returning,
matching the fallback path and GNU’s behavior. `-u` still works
because `now` is already zoned to UTC in that case (date.rs:362),
and the final output stage still applies `with_time_zone(TimeZone::UTC)`
when `settings.utc` is set.

Un-ignores the existing regression test for this issue.

Fixes uutils/parse_datetime#281.
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.

date input: trailing TZ abbreviation (e.g. 2024-01-01 EST) keeps input TZ on output instead of re-zoning

2 participants