…rejects
`formatMeasureDate`'s inline note and the `ISO_DATETIME_RE` docblock both
declared that a well-shaped impossible calendar date such as `2026-02-30` is
unparseable and therefore "keeps falling through to `String(v)`, exactly as it
does today". Measurement says the opposite, on BOTH arms: ECMAScript's Date
Time String Format accepts `DD` in `01`-`31` syntactically and `MakeDay` rolls
the surplus into the next month, so `Date.parse('2026-02-30')` returns an
instant, not `NaN`, and the value renders as `2026-03-02`. What the guard
actually rejects is an out-of-range MONTH (`2026-13-01`), which both patterns
admit.
Comment-only. No behaviour changes, no guard is added, and the pin that holds
the rolled render in place is untouched and still green.
The new prose cites that pin by its test name rather than restating its
conclusion — a comment restating a pin is how the old paragraph came to assert
a behaviour that nothing implemented — and points at the card carrying the open
question of whether the shared display path should refuse an impossible
calendar day at all.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq
Fixes #8263
Comment-only repair in
@object-ui/core'sdataset-format.ts. No behaviour change of anykind. A mechanical pass over
git diff -U0finds no added or removed line that is not acomment; the executable body of
formatMeasureDateis byte-identical toorigin/main.What was wrong
Two sentences in this file asserted that a well-shaped impossible calendar date is unparseable
and therefore keeps falling through to
String(v). Re-measured onorigin/main4dbab84d4,取数时刻 2026-09-19T13:07:59Z,
TZ=UTC, node v22.22.2:Date.parse('2026-02-30')NaN⇒ renders2026-03-02Date.parse('2026-02-30T09:30')NaN⇒ renders2026-03-02T09:30Date.parse('2026-13-01')Date.parse('2026-13-01T09:30')Date.parse('2024-07-04T99:99')The controls fire, so the guard is alive — it simply never rejected a DAY that overflows its
month. ECMAScript's Date Time String Format accepts
DDin01-31syntactically andMakeDayrolls the surplus into the next month. What the guard rejects is an out-of-rangeMONTH, which both patterns admit.
Before / after — every sentence that changed
1. The
ISO_DATETIME_REdocblockBefore:
After:
2. The inline note inside
formatMeasureDateBefore:
After:
⭐ Why this is the prose half and not the code half
The first dispatch on this card asked for the opposite repair — make the code fall through, as
the old comment promised. That direction was withdrawn by the dispatching seat after measurement
showed the file carries a second declaration which says the opposite and which, unlike the
prose, is enforced: the green pin
agrees with the list cell on a rolled-over date instead of second-guessing it, whose own comment ends 「Pinned because it is the one place agreement lookslike a bug.」
Two readings made the choice:
new Date(v).toISOString().slice(0,10) === vcompares a ten-character slice against the whole string, so it answers
falsefor the realinstant
2026-02-28T09:30:00.000Z(control2026-02-28answerstrue, so the probe isalive). Triage required both arms be handled; that spelling cannot handle one of them.
formatDateis theone shared path behind every date cell, grid card and gantt tooltip, and it renders
2026-02-30asMar 2. A measure tile reading2026-02-30beside a list cell readingMar 2for the same stored string is exactly the divergence this file's header exists toprevent — measured, not assumed, against a byte-identical
date-display.ts(
git hash-object=6cbabb21ccb0eb105722aaaf87b5185b3bfebd2c).So the behaviour stays and the prose becomes true. Whether the shared path should refuse an
impossible calendar day is a product decision about every date surface in the console, and it is
carried separately by objectui#10026 — which also records the asymmetry that turned this up: the
authoring boundary already refuses such a value (
isRealCalendarDatein the filter builder,「A date that exists — the pattern alone would accept
2024-02-31.」) while the display pathrolls it.
Validation
pnpm exec vitest run packages/core/src/utils/__tests__/dataset-format.date.test.tsTest Files 1 passed (1),Tests 23 passed (23), exit 0origin/mainbefore this branchTests 23 passed (23), exit 0pnpm --filter '@object-ui/core^...' buildthenpnpm --filter @object-ui/core run type-checkVERDICT command-exit 0node scripts/check-changeset-presence.mjspnpm check:new-line-citationsVERDICT new-cross-file-line-citations: 0 new citation(s)pnpm check:control-bytesOK (scanned 8079 tracked text file(s))pnpm check:pending-changeset-literalsnode scripts/check-governed-queue-guard.mjs --test …NOT GOVERNED — 2 path(s) checked⭐ The control that matters for a prose-only change is that nothing else moved: the suite
returns the same 23 passing tests it returned on
origin/mainbefore this branch existed. Thepin is untouched — it is not in this diff.
The first type-check attempt exited 2 with
TS6305("Output file … has not been built"), whichis a missing dependency build and not a type error; the row above is the re-run after
pnpm --filter '@object-ui/core^...' build.Acceptance notes
check:changeset-claimsis report-only and it asked one question of this change: a pendingchangeset describes
dataset-format.ts, claiming 「No second date formatter was written」 andthat
formatDate/formatDateTime/formatRelativeDateMOVED into@object-ui/core. Readand still true — this diff adds no formatter, moves nothing, and changes no behaviour.
check:comment-mask-corpusreports one disagreeing file,apps/console/src/pages/DocsIndex.tsx,pre-existing and inside the residue objectui#7882 holds open. Not this diff.
Date the same way」 — a live-sounding claim with no instrument behind it (commandment 完善设计器的每一个细节 #9). I
measured it true today (the date cell renderer routes to
formatDate;ObjectGridimportsformatDate;formatDate('2026-02-30')isMar 2), but nothing re-derives it. 承接者:whoever rules objectui#10026 — same paragraph, same file.
isRealCalendarDatelives in the React package@object-ui/componentswhile the display path lives in
@object-ui/core, so core cannot reach it. Not a defect today;it is the precondition that makes any future shared-path repair a MOVE rather than a second
copy. 承接者: objectui#10026.
Clause-②line, so there was none to copy into thisbody. The changeset decision is stated explicitly instead: empty frontmatter, because a
comment-only edit publishes nothing.
⛔ Landing
Draft on purpose. ⛔ Not to be marked ready, enqueued or auto-merged by me — landing is the
domain:ui#2execution seat's act.Generated by Claude Code