Skip to content

fix: accept Temporal objects in withCalendar - #34

Open
MidnightDesign wants to merge 1 commit into
masterfrom
fix-withcalendar-temporal-object
Open

fix: accept Temporal objects in withCalendar#34
MidnightDesign wants to merge 1 commit into
masterfrom
fix-withcalendar-temporal-object

Conversation

@MidnightDesign

Copy link
Copy Markdown
Owner

Summary

withCalendar deviated from TC39: it typed its parameter as string and rejected Temporal objects with a native TypeError. The spec's ToTemporalCalendarIdentifier has an object fast path — when the argument is a Temporal date-bearing object (PlainDate, PlainDateTime, PlainMonthDay, PlainYearMonth, ZonedDateTime), it returns that object's [[Calendar]].

This came out of a re-investigation of the test262 "transpiler gap" buckets: it was surfacing as a transpiler artifact (Argument #1 ($calendar) must be of type string, … PlainDate given) but was a genuine spec bug.

Changes

  • Spec layer (PlainDate, PlainDateTime, ZonedDateTime): widen the parameter to mixed, resolve via the existing CalendarFactory::resolveBagCalendar() (object-with-calendarId → read slot; string → parse; non-string non-object → TypeError; unknown calendar string → RangeError).
  • Porcelain layer: widen the union to accept the five date-bearing value types alongside Calendar, via a new Calendar::resolve() helper.
  • Added PlainDateTest::testWithCalendarAcceptsTemporalObject.

Per-commit impact

c729ae46 — unlocks 6 test262 fixtures (withCalendar/calendar-temporal-object{,-objects} × {PlainDate, PlainDateTime, ZonedDateTime}). test262 incomplete 417 → 411, 0 failures. Full composer check green: PHPStan 9 / Psalm 1 / Mago clean; Infection 100% covered MSI (563 mutations, 0 escaped, 0 uncovered).

🤖 Generated with Claude Code

… fast path)

TC39's ToTemporalCalendarIdentifier has an object fast path: when the argument
is a Temporal date-bearing object (PlainDate, PlainDateTime, PlainMonthDay,
PlainYearMonth, ZonedDateTime) it returns that object's [[Calendar]] rather
than requiring a string. Our withCalendar typed its parameter as `string` and
rejected such objects with a native TypeError, deviating from the spec.

Spec layer (PlainDate/PlainDateTime/ZonedDateTime): widen the parameter to
`mixed` and resolve via the existing CalendarFactory::resolveBagCalendar(),
which already implements the spec branching (object-with-calendarId -> read
slot; string -> parse; non-string non-object -> TypeError; unknown calendar
string -> RangeError).

Porcelain layer: widen the union to accept the five date-bearing value types
alongside Calendar, resolving through a new Calendar::resolve() helper that
returns a Calendar case as-is or reads the value's own calendar.

Unlocks 6 test262 fixtures (withCalendar/calendar-temporal-object{,-objects}
for PlainDate, PlainDateTime, ZonedDateTime); test262 incomplete 417 -> 411,
0 failures. Full `composer check` green: PHPStan 9 / Psalm 1 / Mago clean,
Infection 100% covered MSI (563 mutations, 0 escaped, 0 uncovered).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@MidnightDesign MidnightDesign changed the title Accept Temporal objects in withCalendar (ToTemporalCalendarIdentifier fast path) fix: accept Temporal objects in withCalendar Aug 17, 2026
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.

1 participant