Skip to content

Commit

Permalink
Normative: Treat daysInMonth as count of all days rather than numbe…
Browse files Browse the repository at this point in the history
…r of the last day

Updates PlainYearMonth arithmetic accordingly and clarifies language
around non-ISO calendar operations.

Fixes #1315

Co-authored-by: Guillaume Emont <[email protected]>
  • Loading branch information
2 people authored and ptomato committed Apr 28, 2023
1 parent d1161a1 commit eb2a26f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
17 changes: 14 additions & 3 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4735,13 +4735,24 @@ export function AddDurationToOrSubtractDurationFromPlainYearMonth(operation, yea
const calendar = GetSlot(yearMonth, CALENDAR);
const fieldNames = CalendarFields(calendar, ['monthCode', 'year']);
const fields = PrepareTemporalFields(yearMonth, fieldNames, []);
const fieldsCopy = ObjectCreate(null);
CopyDataProperties(fieldsCopy, fields, []);
fields.day = 1;
let startDate = CalendarDateFromFields(calendar, fields);
const sign = DurationSign(years, months, weeks, days, 0, 0, 0, 0, 0, 0);
fields.day = sign < 0 ? CalendarDaysInMonth(calendar, yearMonth) : 1;
const startDate = CalendarDateFromFields(calendar, fields);
const dateAdd = GetMethod(calendar, 'dateAdd');
const Duration = GetIntrinsic('%Temporal.Duration%');
if (sign < 0) {
const oneMonthDuration = new Duration(0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
const nextMonth = CalendarDateAdd(calendar, startDate, oneMonthDuration, undefined, dateAdd);
const minusDayDuration = new Duration(0, 0, 0, -1, 0, 0, 0, 0, 0, 0);
const endOfMonth = CalendarDateAdd(calendar, nextMonth, minusDayDuration, undefined, dateAdd);
fieldsCopy.day = CalendarDay(calendar, endOfMonth);
startDate = CalendarDateFromFields(calendar, fieldsCopy);
}
const durationToAdd = new Duration(years, months, weeks, days, 0, 0, 0, 0, 0, 0);
const optionsCopy = CopyOptions(options);
const addedDate = CalendarDateAdd(calendar, startDate, durationToAdd, options);
const addedDate = CalendarDateAdd(calendar, startDate, durationToAdd, options, dateAdd);
const addedDateFields = PrepareTemporalFields(addedDate, fieldNames, []);

return CalendarYearMonthFromFields(calendar, addedDateFields, optionsCopy);
Expand Down
18 changes: 14 additions & 4 deletions spec/plainyearmonth.html
Original file line number Diff line number Diff line change
Expand Up @@ -666,16 +666,26 @@ <h1>
1. Let _calendar_ be _yearMonth_.[[Calendar]].
1. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"monthCode"*, *"year"* »).
1. Let _fields_ be ? PrepareTemporalFields(_yearMonth_, _fieldNames_, «»).
1. Let _fieldsCopy_ be OrdinaryObjectCreate(*null*).
1. Perform ! CopyDataProperties(_fieldsCopy_, _fields_, «»).
1. Perform ! CreateDataPropertyOrThrow(_fields_, *"day"*, *1*<sub>𝔽</sub>).
1. Let _intermediateDate_ be ? CalendarDateFromFields(_calendar_, _fields_).
1. Let _sign_ be ! DurationSign(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _balanceResult_.[[Days]], 0, 0, 0, 0, 0, 0).
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _sign_ &lt; 0, then
1. Let _day_ be ? CalendarDaysInMonth(_calendar_, _yearMonth_).
1. Let _oneMonthDuration_ be ! CreateTemporalDuration(0, 1, 0, 0, 0, 0, 0, 0, 0, 0).
1. Let _nextMonth_ be ? CalendarDateAdd(_calendar_, _intermediateDate_, _oneMonthDuration_, *undefined*, _dateAdd_).
1. Let _minusDayDuration_ be ! CreateTemporalDuration(0, 0, 0, -1, 0, 0, 0, 0, 0, 0).
1. Let _endOfMonth_ be ? CalendarDateAdd(_calendar_, _nextMonth_, _minusDayDuration_, *undefined*, _dateAdd_).
1. Let _day_ be ? CalendarDay(_calendar_, _endOfMonth_).
1. Perform ! CreateDataPropertyOrThrow(_fieldsCopy_, *"day"*, _day_).
1. Let _date_ be ? CalendarDateFromFields(_calendar_, _fieldsCopy_).
1. Else,
1. Let _day_ be 1.
1. Perform ! CreateDataPropertyOrThrow(_fields_, *"day"*, 𝔽(_day_)).
1. Let _date_ be ? CalendarDateFromFields(_calendar_, _fields_).
1. Let _date_ be _intermediateDate_.
1. Let _durationToAdd_ be ! CreateTemporalDuration(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _balanceResult_.[[Days]], 0, 0, 0, 0, 0, 0).
1. Let _optionsCopy_ be ? CopyOptions(_options_).
1. Let _addedDate_ be ? CalendarDateAdd(_calendar_, _date_, _durationToAdd_, _options_).
1. Let _addedDate_ be ? CalendarDateAdd(_calendar_, _date_, _durationToAdd_, _options_, _dateAdd_).
1. Let _addedDateFields_ be ? PrepareTemporalFields(_addedDate_, _fieldNames_, «»).
1. Return ? CalendarYearMonthFromFields(_calendar_, _addedDateFields_, _optionsCopy_).
</emu-alg>
Expand Down

0 comments on commit eb2a26f

Please sign in to comment.