Skip to content

Surprising behavior with PlainYearMonth subtraction and constraining #3197

@catamorphism

Description

@catamorphism

(Initially discovered by @ptomato)

In the reference implementation, Temporal.PlainYearMonth.from({ year: 2024, monthCode: 'M02' }).subtract({ years: 1 }, { overflow: 'reject' }) throws:

Uncaught RangeError: value out of range: 1 <= 29 <= 28
    at RejectToRange (file:///home/tjc/proposal-temporal/polyfill/lib/ecmascript.mjs:2784:41)
    at RejectISODate (file:///home/tjc/proposal-temporal/polyfill/lib/ecmascript.mjs:2789:3)
    at Module.RegulateISODate (file:///home/tjc/proposal-temporal/polyfill/lib/ecmascript.mjs:697:7)
    at Object.dateAdd (file:///home/tjc/proposal-temporal/polyfill/lib/calendar.mjs:202:32)
    at CalendarDateAdd (file:///home/tjc/proposal-temporal/polyfill/lib/ecmascript.mjs:1713:46)
    at Module.AddDurationToYearMonth (file:///home/tjc/proposal-temporal/polyfill/lib/ecmascript.mjs:4144:21)
    at Temporal.PlainYearMonth.subtract (file:///home/tjc/proposal-temporal/polyfill/lib/plainyearmonth.mjs:96:15)

This behavior is consistent with the spec, because AddDurationToYearMonth constructs a full date from a YearMonth and passes it to CalendarDateAdd; the date's day is the last day of the same month (when subtracting). So in this case, the date 2024-02-29 is passed to CalendarDateAdd; because the overflow setting is reject, it's rejected because there is no 2023-02-29 in the ISO calendar.

This seems like it would be surprising to users. For YearMonth, overflow would be expected to apply to years and months, but not days, since there is no day visible to the user.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions