Skip to content

Commit 5d81583

Browse files
committed
Editorial: Include ISO 8601 algorithm in CalendarDateToISO
Move the ISO 8601 code from CalendarDateFromFields and CalendarYearMonthFromFields into CalendarDateToISO. At this point it just consists of RegulateISODate anyway. To achieve this, we also drop the requirement that CalendarDateToISO checks its return value is in the representable range, instead moving that to CalendarDateFromFields and CalendarYearMonthFromFields since it is different in both cases. See: #2948 Closes: #2998
1 parent bd041c3 commit 5d81583

File tree

3 files changed

+27
-30
lines changed

3 files changed

+27
-30
lines changed

polyfill/lib/calendar.mjs

+2-6
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,12 @@ impl['iso8601'] = {
138138
dateFromFields(fields, overflow) {
139139
requireFields(fields, ['year', 'day']);
140140
let { year, month, day } = resolveNonLunisolarMonth(fields);
141-
({ year, month, day } = ES.RegulateISODate(year, month, day, overflow));
142-
ES.RejectDateRange(year, month, day);
143-
return { year, month, day };
141+
return ES.RegulateISODate(year, month, day, overflow);
144142
},
145143
yearMonthFromFields(fields, overflow) {
146144
requireFields(fields, ['year']);
147145
let { year, month } = resolveNonLunisolarMonth(fields);
148-
({ year, month } = ES.RegulateISODate(year, month, 1, overflow));
149-
ES.RejectYearMonthRange(year, month);
150-
return { year, month, /* reference */ day: 1 };
146+
return ES.RegulateISODate(year, month, 1, overflow);
151147
},
152148
monthDayFromFields(fields, overflow) {
153149
requireFields(fields, ['day']);

polyfill/lib/ecmascript.mjs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1956,11 +1956,15 @@ export function CalendarEquals(one, two) {
19561956
}
19571957

19581958
export function CalendarDateFromFields(calendar, fields, overflow) {
1959-
return GetIntrinsic('%calendarImpl%')(calendar).dateFromFields(fields, overflow);
1959+
const result = GetIntrinsic('%calendarImpl%')(calendar).dateFromFields(fields, overflow);
1960+
RejectDateRange(result.year, result.month, result.day);
1961+
return result;
19601962
}
19611963

19621964
export function CalendarYearMonthFromFields(calendar, fields, overflow) {
1963-
return GetIntrinsic('%calendarImpl%')(calendar).yearMonthFromFields(fields, overflow);
1965+
const result = GetIntrinsic('%calendarImpl%')(calendar).yearMonthFromFields(fields, overflow);
1966+
RejectYearMonthRange(result.year, result.month);
1967+
return result;
19641968
}
19651969

19661970
export function CalendarMonthDayFromFields(calendar, fields, overflow) {

spec/calendar.html

+19-22
Original file line numberDiff line numberDiff line change
@@ -830,12 +830,11 @@ <h1>
830830
1. If _calendar_ is *"iso8601"*, then
831831
1. If _fields_.[[Year]] is ~unset~ or _fields_.[[Day]] is ~unset~, throw a *TypeError* exception.
832832
1. Perform ? ISOResolveMonth(_fields_).
833-
1. Assert: _fields_.[[Month]] is not ~unset~.
834-
1. Let _result_ be ? RegulateISODate(_fields_.[[Year]], _fields_.[[Month]], _fields_.[[Day]], _overflow_).
835-
1. If ISODateWithinLimits(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]]) is *false*, throw a *RangeError* exception.
836-
1. Return _result_.
837-
1. Perform ? CalendarResolveFields(_calendar_, _fields_, ~date~).
838-
1. Return ? CalendarDateToISO(_calendar_, _fields_, _overflow_).
833+
1. Else,
834+
1. Perform ? CalendarResolveFields(_calendar_, _fields_, ~date~).
835+
1. Let _result_ be ? CalendarDateToISO(_calendar_, _fields_, _overflow_).
836+
1. If ISODateWithinLimits(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]]) is *false*, throw a *RangeError* exception.
837+
1. Return _result_.
839838
</emu-alg>
840839
</emu-clause>
841840

@@ -855,18 +854,13 @@ <h1>
855854
1. If _calendar_ is *"iso8601"*, then
856855
1. If _fields_.[[Year]] is ~unset~, throw a *TypeError* exception.
857856
1. Perform ? ISOResolveMonth(_fields_).
858-
1. Assert: _fields_.[[Month]] is not ~unset~.
859-
1. Let _result_ be ? RegulateISODate(_fields_.[[Year], _fields_.[[Month]], 1, _overflow_).
860-
1. If ISOYearMonthWithinLimits(_result_.[[Year]], _result_.[[Month]]) is *false*, throw a *RangeError* exception.
861-
1. Return ISO Date Record {
862-
[[Year]]: _result_.[[Year]],
863-
[[Month]]: _result_.[[Month]],
864-
[[Day]]: 1
865-
}.
857+
1. Else,
858+
1. Perform ? CalendarResolveFields(_calendar_, _fields_, ~year-month~).
866859
1. Let _firstDayIndex_ be the 1-based index of the first day of the month described by _fields_ (i.e., 1 unless the month's first day is skipped by this calendar.)
867860
1. Set _fields_.[[Day]] to _firstDayIndex_.
868-
1. Perform ? CalendarResolveFields(_calendar_, _fields_, ~year-month~).
869-
1. Return ? CalendarDateToISO(_calendar_, _fields_, _overflow_).
861+
1. Let _result_ be ? CalendarDateToISO(_calendar_, _fields_, _overflow_).
862+
1. If ISOYearMonthWithinLimits(_result_.[[Year]], _result_.[[Month]]) is *false*, throw a *RangeError* exception.
863+
1. Return _result_.
870864
</emu-alg>
871865
</emu-clause>
872866

@@ -1116,7 +1110,7 @@ <h1>
11161110
<emu-clause id="sec-temporal-calendardatetoiso" type="implementation-defined abstract operation">
11171111
<h1>
11181112
CalendarDateToISO (
1119-
_calendar_: a calendar type that is not *"iso8601"*,
1113+
_calendar_: a calendar type,
11201114
_fields_: a Calendar Fields Record,
11211115
_overflow_: ~constrain~ or ~reject~,
11221116
): either a normal completion containing an ISO Date Record or a throw completion
@@ -1129,11 +1123,14 @@ <h1>
11291123
For ~constrain~, values that do not form a valid date are clamped to their respective valid range.
11301124
</dd>
11311125
</dl>
1132-
<p>
1133-
Like RegulateISODate, the operation throws a *RangeError* exception when _overflow_ is ~reject~ and the date described by _fields_ does not exist.
1134-
It also throws a *RangeError* exception if the date described by _fields_ is outside the range allowed by ISODateWithinLimits.
1135-
</p>
1136-
<p>Clamping an invalid date to the correct range when _overflow_ is ~constrain~ is a behaviour specific to each built-in calendar, but all built-in calendars follow this guideline:</p>
1126+
<emu-alg>
1127+
1. If _calendar_ is *"iso8601"*, then
1128+
1. Assert: _fields_.[[Year]], _fields_.[[Month]], and _fields_.[[Day]] are not ~unset~.
1129+
1. Return ? RegulateISODate(_fields_.[[Year]], _fields_.[[Month]], _fields_.[[Day]], _overflow_).
1130+
1. Return an implementation-defined ISO Date Record, or throw a *RangeError* exception, as described below.
1131+
</emu-alg>
1132+
<p>Like RegulateISODate, the operation throws a *RangeError* exception when _overflow_ is ~reject~ and the date described by _fields_ does not exist.</p>
1133+
<p>Clamping an invalid date to the correct range when _overflow_ is ~constrain~ is a behaviour specific to each calendar other than *"iso8601"*, but all calendars follow this guideline:</p>
11371134
<ul>
11381135
<li>Pick the closest day in the same month. If there are two equally-close dates in that month, pick the later one.</li>
11391136
<li>If the month is a leap month that doesn't exist in the year, pick another date according to the cultural conventions of that calendar's users. Usually this will result in the same day in the month before or after where that month would normally fall in a leap year.</li>

0 commit comments

Comments
 (0)