Recompute ZonedDateTime UTC offset after rounding (#358)#362
Conversation
- Fix `toString()` when rounding carries into a new day - Add regression tests for UTC and fixed-offset zones
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughDefers UTC offset recomputation in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@source/units/Goccia.Values.TemporalZonedDateTime.pas`:
- Around line 1149-1153: The code recomputes the UTC offset unconditionally by
calling LocalToEpochMs and GetUtcOffsetSeconds even when RoundTimeForToString
produced no change; this can flip the DST fold for ambiguous times. Add a guard
that computes a RoundedChanged boolean by comparing the pre-round local fields
(DateRec.Year/Month/Day, LHour/LMinute/LSecond/LMs) plus ExtraDays against the
post-round values, and only call LocalToEpochMs to set RoundedEpochMs and
recompute OffsetSeconds via GetUtcOffsetSeconds when RoundedChanged is true;
otherwise preserve the original offset from the input epoch. Ensure you
reference RoundTimeForToString, LocalToEpochMs, RoundedEpochMs, OffsetSeconds,
GetUtcOffsetSeconds and ExtraDays when implementing the guard.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d468eaea-5756-4808-9298-8efacbab4475
📒 Files selected for processing (2)
source/units/Goccia.Values.TemporalZonedDateTime.pastests/built-ins/Temporal/ZonedDateTime/prototype/toString.js
Benchmark Results386 benchmarks Interpreted: 🟢 30 improved · 🔴 111 regressed · 245 unchanged · avg -1.5% arraybuffer.js — Interp: 🟢 1, 🔴 2, 11 unch. · avg -0.7% · Bytecode: 🟢 8, 🔴 1, 5 unch. · avg +6.6%
arrays.js — Interp: 🔴 6, 13 unch. · avg -0.8% · Bytecode: 🟢 18, 1 unch. · avg +11.6%
async-await.js — Interp: 🔴 1, 5 unch. · avg -1.7% · Bytecode: 🟢 5, 1 unch. · avg +9.8%
base64.js — Interp: 🔴 5, 5 unch. · avg -1.8% · Bytecode: 🟢 8, 2 unch. · avg +5.8%
classes.js — Interp: 🟢 1, 🔴 4, 26 unch. · avg -0.9% · Bytecode: 🟢 18, 13 unch. · avg +5.7%
closures.js — Interp: 🔴 2, 9 unch. · avg -1.0% · Bytecode: 🟢 11 · avg +11.1%
collections.js — Interp: 🟢 2, 🔴 1, 9 unch. · avg +0.6% · Bytecode: 🟢 12 · avg +11.2%
csv.js — Interp: 🔴 1, 12 unch. · avg -0.5% · Bytecode: 🟢 12, 1 unch. · avg +9.4%
destructuring.js — Interp: 🔴 8, 14 unch. · avg -2.1% · Bytecode: 🟢 21, 1 unch. · avg +8.2%
fibonacci.js — Interp: 🔴 1, 7 unch. · avg -0.2% · Bytecode: 🟢 8 · avg +12.1%
float16array.js — Interp: 🟢 6, 🔴 1, 25 unch. · avg +0.7% · Bytecode: 🟢 27, 5 unch. · avg +16.8%
for-of.js — Interp: 7 unch. · avg -0.0% · Bytecode: 🟢 7 · avg +14.8%
helpers/bench-module.js — Interp: 0 · Bytecode: 0
iterators.js — Interp: 🟢 1, 🔴 20, 21 unch. · avg -2.4% · Bytecode: 🟢 33, 🔴 1, 8 unch. · avg +6.2%
json.js — Interp: 🔴 6, 14 unch. · avg -1.9% · Bytecode: 🟢 20 · avg +10.7%
jsx.jsx — Interp: 🟢 7, 🔴 3, 11 unch. · avg +0.2% · Bytecode: 🟢 15, 6 unch. · avg +5.1%
modules.js — Interp: 🔴 2, 7 unch. · avg -1.7% · Bytecode: 🟢 9 · avg +17.3%
numbers.js — Interp: 🟢 1, 🔴 2, 8 unch. · avg +0.7% · Bytecode: 🟢 10, 1 unch. · avg +7.1%
objects.js — Interp: 🔴 2, 5 unch. · avg -2.2% · Bytecode: 🟢 7 · avg +8.6%
promises.js — Interp: 🟢 2, 🔴 3, 7 unch. · avg -0.7% · Bytecode: 🟢 6, 🔴 1, 5 unch. · avg +2.9%
regexp.js — Interp: 🟢 1, 10 unch. · avg +1.1% · Bytecode: 🟢 10, 1 unch. · avg +10.1%
strings.js — Interp: 🟢 1, 🔴 12, 6 unch. · avg +2.8% · Bytecode: 🟢 13, 🔴 2, 4 unch. · avg +1.5%
tsv.js — Interp: 🟢 6, 3 unch. · avg +3.9% · Bytecode: 🟢 7, 2 unch. · avg +6.9%
typed-arrays.js — Interp: 🔴 19, 3 unch. · avg -4.2% · Bytecode: 🟢 12, 🔴 7, 3 unch. · avg +2.5%
uint8array-encoding.js — Interp: 🟢 1, 🔴 10, 7 unch. · avg -16.2% · Bytecode: 🟢 14, 4 unch. · avg +37.3%
Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context. |
Suite Timing
Measured on ubuntu-latest x64. |
Only recompute the UTC offset via LocalToEpochMs when rounding actually changed the local time components. Unconditional re-resolution through LocalToEpochMs uses first-match disambiguation, which can flip the fold for ambiguous wall-clock times during DST fall-back. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
ZonedDateTimeToStringnow recomputes the UTC offset afterRoundTimeForToString(and any day carry), ensuring the formatted string reflects the correct offset for the rounded instant rather than the pre-rounding one.LocalToEpochMsto derive the rounded epoch, then callsGetUtcOffsetSecondson it.+05:30).🤖 Generated with Claude Code