Skip to content

fix(builder): handle wall-clock times in a DST gap like GNU date - #346

Open
jayhemnani9910 wants to merge 1 commit into
uutils:mainfrom
jayhemnani9910:reject-nonexistent-local-time
Open

jayhemnani9910 wants to merge 1 commit into
uutils:mainfrom
jayhemnani9910:reject-nonexistent-local-time

Conversation

@jayhemnani9910

Copy link
Copy Markdown
Contributor

Two problems with times in a DST gap (New York skips 02:00-03:00 on 2024-03-10):

$ TZ=America/New_York gnudate -d '2024-03-10 02:30'          # GNU coreutils 9.7
gnudate: invalid date '2024-03-10 02:30'
parse_datetime:                                               2024-03-10T03:30:00-04:00

$ TZ=America/New_York gnudate -u -d '2024-03-10 02:30 UTC' +%FT%TZ
2024-03-10T02:30:00Z
parse_datetime:                                               2024-03-10T03:30:00+00:00

The first is a time that doesn't exist; jiff's default disambiguation moves it past the gap, and GNU rejects it. The second is wrong by an hour: the date and time are first placed in the local zone, where 02:30 doesn't exist and becomes 03:30, and only then is the written zone applied to that wall clock. 02:30Z and T02:30:00Z are affected too; 02:30 +00:00 was already right because the time's own offset is applied first.

build_in_range now keeps the wall-clock time the input asked for. If the local zone moved it, the input named a time in a gap and is rejected. If the input carries a zone (UTC, Z, an offset), that zone is applied to the requested wall-clock time instead of the locally resolved one. A relative item that lands in a gap (2018-11-03 +1 day in Sao Paulo) still moves past it, as GNU does, and times in the repeated hour still take the first offset.

Tests: test_local_time_in_dst_gap_is_invalid, test_dst_gap_neighbours and test_relative_item_moves_past_dst_gap in tests/date.rs; 5 of the 9 cases fail on main. cargo test: 491 passed; clippy and fmt clean. 22 inputs in 6 zones (New York, Sao Paulo, Berlin, Lord Howe, Kolkata, UTC), covering gaps, the repeated hour, written zones and offsets, weekdays and relative items, give the same instant or error as GNU date 9.7.

A date or time that falls in the local zone's DST gap was moved past the
gap by jiff (2024-03-10 02:30 in New York became 03:30). GNU date
rejects it as an invalid date, so do the same. A time written with its
own zone ("2024-03-10 02:30 UTC", "...T02:30:00Z") was built in the
local zone first and so came out an hour late; apply the zone to the
wall-clock time as written. A relative item that lands in a gap still
moves past it, as in GNU.
Copilot AI balanced review requested due to automatic review settings October 27, 2026 06:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@codspeed

codspeed Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 4.36%

2 warnings

⚠️ 14 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

❌ 3 regressed benchmarks
✅ 18 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ parse_epoch_timestamp 11.3 µs 11.9 µs -4.61%
❌ parse_date_only 27.8 µs 29.1 µs -4.49%
❌ parse_weekday 40.9 µs 42.6 µs -3.99%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing jayhemnani9910:reject-nonexistent-local-time (0d9240f) with main (37d5d78)

Open in CodSpeed

@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.90%. Comparing base (d434521) to head (0d9240f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #346   +/-   ##
=======================================
  Coverage   98.89%   98.90%           
=======================================
  Files          21       21           
  Lines        4540     4567   +27     
  Branches      142      144    +2     
=======================================
+ Hits         4490     4517   +27     
  Misses         49       49           
  Partials        1        1           
Flag Coverage Δ
macos_latest 98.90% <100.00%> (+<0.01%) ⬆️
ubuntu_latest 98.90% <100.00%> (+<0.01%) ⬆️
windows_latest 12.28% <39.13%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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