ReviewOS

zig-utils/zig-js

Date: apply TimeClip after local-to-UTC conversion

#1062
Closed chris opened this 9 days ago ·
9 days ago

Parent: #475 Discovered by: #1061

Two pinned Date.toISOString cases fail before any constructor-lookup change: prototype/toISOString/15.9.5.43-0-9.js and 15.9.5.43-0-10.js, both with RangeError: Invalid Date.

Executed reproduction uses the process timezone (America/Los_Angeles):

let offset = -new Date(0).getTimezoneOffset();
let a = new Date(1970, 0, -99999999, 0, offset + 60, 0, 0);
let b = new Date(1970, 0, -99999999, 0, offset + 60, 0, 1);
[offset, Number.isNaN(a.getTime()), Number.isNaN(b.getTime())].join(",");

Node: -480,false,false. Saved engine binary in tree and required-bytecode modes: -480,true,true.

The local component builder applies TimeClip before timezone conversion, and the local-to-UTC helper also rejects inputs outside the final UTC range. UTC conversion must precede TimeClip; valid boundary instants can have local wall-clock values outside that range. See ECMA-262 UTC(t), 21.4.1.26, and the Date constructor algorithm.

Acceptance:

  • Compute local component time without clipping, convert to UTC, then apply TimeClip.
  • Preserve Date.UTC/direct numerical Date clipping and reject unrepresentable/extreme inputs safely.
  • Pin both range boundaries, milliseconds, constructors and local setters, fixed offsets of both signs, and ordinary/DST behavior.
  • Normal/unsuppressed TSan and tree/required-bytecode witnesses pass.
  • Full pinned Date corpus improves from 592 pass / 2 fail to 594 pass / 0 fail with exact failure-path accounting.
9 days ago

Fixed in ff04953.

Local component construction now preserves the unclipped MakeDate value through UTC conversion, then applies TimeClip. Local setters use the same conversion contract. Date.UTC and direct numerical Date construction retain direct clipping, with non-finite inputs rejected before timezone discovery and extreme inputs bounded safely.

The saved before probe returned -480,true,true; both after modes now return Node's -480,false,false. Fixed-offset constructor/setter matrices match Node under Etc/GMT+8 and Etc/GMT-9. Tests also cover both Date range edges, inward/outward ±1 ms, UTC, huge/infinite inputs, and the New York DST overlap/gap instants.

Validation: 4/4 normal and 4/4 under unsuppressed TSan, including required-bytecode isolated/shared contexts and the existing IANA-zone fixture. The full pinned Date corpus improves from 592 pass / 2 fail to 594 pass / 0 fail. Exact gains are prototype/toISOString/15.9.5.43-0-9.js and 15.9.5.43-0-10.js; regression set is empty. The final tree/VM witness has 594 agreements and zero divergences. Inventory passes.

This follows the UTC-before-TimeClip order in ECMA-262 UTC. The global published Test262 score is not inferred from this scoped run.

Sign in to comment on this issue.