js-on-sx: Date.UTC and new Date propagate NaN/Infinity args
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 4m20s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 4m20s
This commit is contained in:
@@ -1111,8 +1111,10 @@
|
||||
(v)
|
||||
(cond
|
||||
((number? v) v)
|
||||
((= (type-of v) "rational") (exact->inexact v))
|
||||
((= (type-of v) "string") (js-date-parse-string v))
|
||||
(else 0))))
|
||||
((js-undefined? v) (js-nan-value))
|
||||
(else (js-to-number v)))))
|
||||
|
||||
(define
|
||||
js-date-parse-string
|
||||
@@ -1159,6 +1161,26 @@
|
||||
(* secs 1000)
|
||||
ms))))))
|
||||
|
||||
(define
|
||||
js-date-args-have-nan?
|
||||
(fn
|
||||
(args i)
|
||||
(cond
|
||||
((>= i (len args)) false)
|
||||
(else
|
||||
(let
|
||||
((n (js-to-number (nth args i))))
|
||||
(cond
|
||||
((or (number? n) (= (type-of n) "rational"))
|
||||
(let
|
||||
((nf (if (= (type-of n) "rational") (exact->inexact n) n)))
|
||||
(cond
|
||||
((js-number-is-nan nf) true)
|
||||
((= nf (js-infinity-value)) true)
|
||||
((= nf (- 0 (js-infinity-value))) true)
|
||||
(else (js-date-args-have-nan? args (+ i 1))))))
|
||||
(else (js-date-args-have-nan? args (+ i 1)))))))))
|
||||
|
||||
(define
|
||||
js-date-civil-to-days
|
||||
(fn
|
||||
@@ -1219,6 +1241,7 @@
|
||||
(cond
|
||||
((= (len args) 0) 0)
|
||||
((= (len args) 1) (js-date-from-one (nth args 0)))
|
||||
((js-date-args-have-nan? args 0) (js-nan-value))
|
||||
(else (js-date-from-parts args))))
|
||||
(dict-set! this "__js_is_date__" true)
|
||||
this)))))
|
||||
@@ -1228,8 +1251,15 @@
|
||||
(fn
|
||||
(&rest args)
|
||||
(cond
|
||||
((= (len args) 0) 0)
|
||||
(else (js-date-from-parts args))))
|
||||
((= (len args) 0) (js-nan-value))
|
||||
((js-date-args-have-nan? args 0) (js-nan-value))
|
||||
(else
|
||||
(let
|
||||
((ms (js-date-from-parts args)))
|
||||
(cond
|
||||
((or (> ms 8640000000000000) (< ms -8640000000000000))
|
||||
(js-nan-value))
|
||||
(else ms))))))
|
||||
:prototype
|
||||
{:getTime (fn () (js-date-time-value (js-this)))
|
||||
:valueOf (fn () (js-date-time-value (js-this)))
|
||||
|
||||
@@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green.
|
||||
|
||||
Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta.
|
||||
|
||||
- 2026-05-10 — **`Date.UTC` / `new Date(...)` propagate NaN/±Infinity arguments and return NaN.** `Date.UTC()` (no args) returned 0 instead of NaN; `Date.UTC(NaN, ...)` did the math and produced bogus ms; `new Date(year, NaN)` constructed a normal Date instead of an invalid one. Added `js-date-args-have-nan?` (also detects ±Infinity and propagates from rationals) used by both `Date.UTC` and the multi-arg constructor branch; UTC now returns NaN on no-arg / any-NaN-arg / out-of-range result, and `new Date(args)` stores NaN in `__date_value__` when any arg is NaN. Also fixed `js-date-from-one(undefined)` to return NaN. Result: built-ins/Date/UTC 6/16 → 10/16 (+4). Date 17/30 → 26/30 (timeouts dropped from 12 → 4 because invalid Dates now short-circuit). conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-10 — **Real `Date` construction + getters via Howard-Hinnant civil-day arithmetic.** `js-date-from-parts` now computes a true ms-since-epoch from `(year, month, day, hour, min, sec, ms)` via `js-date-civil-to-days` (the inverse of last iteration's `days-to-ymd`), with the legacy 2-digit-year coercion (0..99 → 1900+y). `getFullYear/Month/Date/Day/Hours/Minutes/Seconds/Milliseconds` (UTC + non-UTC) all share a new `js-date-getter`: TypeErrors on non-Date this, returns NaN on invalid time, otherwise decomposes ms into y/m/d/h/m/s/ms/dow. Plus added `Date.prototype.constructor = Date` (was missing). Result: each of the 8 Date getter categories went 2/6 → 5/6 (+3 each, +24 total). Date toISOString 11/16 → 13/16. Some Date construction-loop tests now exceed the 15s per-test timeout — the new civil math is heavier than the old (year-1970)*ms-per-year approximation, but correctness wins. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-10 — **`Date.prototype.toISOString` produces real `YYYY-MM-DDTHH:mm:ss.sssZ` and validates input.** Old `js-date-iso` only computed the year and hardcoded the rest as `01-01T00:00:00.000Z`. Added: (1) TypeError when this isn't a Date (no `__js_is_date__` slot); (2) RangeError when ms is NaN, undefined, or |ms| > 8.64e15; (3) full date breakdown via Howard-Hinnant `days_to_civil` algorithm (`js-date-days-to-ymd`) → year/month/day, plus modular hours/min/sec/ms; (4) extended-year format `±YYYYYY` for years outside 0..9999. Result: built-ins/Date/prototype/toISOString 7/16 → 11/16 (+4). Date 21/30. conformance.sh: 148/148.
|
||||
|
||||
Reference in New Issue
Block a user