Skip to content

Commit 5e3fac2

Browse files
committed
Migrate NonISOCalendarDateToISO
1 parent d423175 commit 5e3fac2

File tree

1 file changed

+71
-59
lines changed

1 file changed

+71
-59
lines changed

spec.emu

Lines changed: 71 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ contributors: Google, Ecma International
729729
</h1>
730730
<dl class="header">
731731
<dt>description</dt>
732-
<dd>It produces the year relative to the epoch year (the arithmetic year) for a given set of era, eraYear for a calendar that has eras.</dd>
732+
<dd>It produces the year relative to the epoch year (the arithmetic year) for a given set of _era_, _eraYear_ in _calendar_, a calendar that includes an era named _era_.</dd>
733733
</dl>
734734
<emu-alg>
735735
1. Let _era_ be CanonicalizeEraInCalendar(_calendar_, _era_).
@@ -902,16 +902,19 @@ contributors: Google, Ecma International
902902
<p>This definition supersedes the definition provided in <emu-xref href="#sec-temporal-nonisodateadd"></emu-xref>.</p>
903903
<p>It performs the following steps when called:</p>
904904
<emu-alg>
905-
1. Let _yearMonth_ be RegulateNonISOYearMonth(_calendar_, _isoDate_, _duration_.[[Years]]).
905+
1. Let _parts_ be CalendarISOToDate(_calendar_, _baseDate_).
906+
1. Let _yearMonth_ be RegulateNonISOYearMonth(_calendar_, _parts_.[[Year]], _parts_.[[MonthCode]], _duration_.[[Years]]).
906907
1. Let _endOfMonth_ be BalanceNonISODate(_calendar_, _yearMonth_.[[Year]], _yearMonth_.[[Month]] + _duration_.[[Months]] + 1, 0).
907-
1. Let _baseDay_ be CalendarISOToDate(_calendar_, _isoDate_).[[Day]].
908+
1. Let _baseDay_ be _parts_.[[Day]].
908909
1. If _endOfMonth_.[[Day]] &lt; _baseDay_, then
909910
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
910911
1. Let _regulatedDay_ be _endOfMonth_.[[Day]].
911912
1. Else,
912913
1. Let _regulatedDay_ be _baseDay_.
913914
1. Let _balancedDate_ be BalanceNonISODate(_calendar_, _endOfMonth_.[[Year]], _endOfMonth_.[[Month]], _regulatedDay_ + 7 * _duration_.[[Weeks]] + _duration_.[[Days]]).
914-
1. Return ? CalendarDateArithmeticalToISO(_calendar_, _balancedDate_.[[Year]], _balancedDate_.[[Month]], _balancedDate_.[[Day]]).
915+
1. Let _result_ be ? CalendarDateArithmeticalToISO(_calendar_, _balancedDate_.[[Year]], _balancedDate_.[[Month]], _balancedDate_.[[Day]]).
916+
1. If ISODateWithinLimits(_result_) is *false*, throw a *RangeError* exception.
917+
1. Return _result_.
915918
</emu-alg>
916919
</emu-clause>
917920

@@ -963,51 +966,42 @@ contributors: Google, Ecma International
963966
</emu-alg>
964967
</emu-clause>
965968

966-
<emu-clause id="sup-temporal-isvalidmonthcodeforcalendarinyear" type="implementation-defined abstract operation">
969+
<emu-clause id="sup-temporal-monthcodetoarithmeticalmonth" type="implementation-defined abstract operation">
967970
<h1>
968-
IsValidMonthCodeForCalendarInYear (
971+
MonthCodeToArithmeticalMonth (
969972
_calendar_: a calendar type that is not *"iso8601"*,
970973
_year_: an integer,
971974
_monthCode_: a String,
972-
): an Boolean
975+
): an integer or ~invalid~
973976
</h1>
974977
<dl class="header">
975978
<dt>description</dt>
976979
<dd>
977-
It interprets _year_ as arithmetical value in the given _calendar_ and returns *true* if there is a month with the given _monthCode_ in that year or *false* otherwise.
980+
It interprets _year_ as arithmetical year in the given _calendar_, returning an integer if there is a month with the given _monthCode_ in that year, or ~invalid~ otherwise.
978981
</dd>
979982
</dl>
980983
<p>It performs the following steps when called:</p>
981984
<emu-alg>
982985
1. If IsValidMonthCodeForCalendar(_calendar_, _monthCode_) is *false*, then
983-
1. Return *false*.
986+
1. Return ~invalid~.
984987
1. Let _monthCodeParts_ be ParseMonthCode(_monthCode_).
985-
1. If _monthCodeParts_.[[IsLeap]] is *false*, then
986-
1. Return *true*.
987-
1. Assert: _calendar_ is one of *"chinese"*, *"dangi"*, or *"hebrew"*.
988-
1. Return a calendar-dependent Boolean as described above.
989-
</emu-alg>
990-
</emu-clause>
991-
992-
<emu-clause id="sup-temporal-calendardatecodestoiso" type="implementation-defined abstract operation">
993-
<h1>
994-
CalendarDateCodesToISO (
995-
_calendar_: a calendar type that is not *"iso8601"*,
996-
_year_: an integer,
997-
_monthCode_: a String,
998-
_day_: an integer,
999-
): either a normal completion containing an ISO Date Record or a throw completion
1000-
</h1>
1001-
<dl class="header">
1002-
<dt>description</dt>
1003-
<dd>
1004-
It returns an ISO Date Record that, when converted to a Calendar Date Record with _calendar_ (for example, with CalendarISOToDate), contains the given _year_, _monthCode_, and _day_ values in its [[Year]], [[MonthCode]], and [[Day]] fields. If this is not possible, a RangeError is thrown.
1005-
</dd>
1006-
</dl>
1007-
<p>It performs the following steps when called:</p>
1008-
<emu-alg>
1009-
1. If _year_, _monthCode_, and _day_ do not form a valid date in _calendar_, throw a RangeError exception.
1010-
1. Return a calendar-dependent ISO Date Record as described above.
988+
1. If _calendar_ is not *"chinese"*, *"dangi"*, or *"hebrew"*, then
989+
1. Return _monthCodeParts_.[[Number]].
990+
1. Let _monthsBefore_ be 0.
991+
1. Let _number_ be 1.
992+
1. Let _isLeap_ be *false*.
993+
1. Repeat, while _number_ &le; 12,
994+
1. Let _intermediate_ be CreateMonthCode(_number_, _isLeap_).
995+
1. If _calendar_ contains _monthCode_ in _year_, according to a calendar-dependent algorithm, then
996+
1. Set _monthsBefore_ to _monthsBefore_ + 1.
997+
1. If _monthCodeParts_.[[Number]] is _number_ and _monthCodeParts.[[IsLeap]] is _isLeap_, then
998+
1. Return _monthsBefore_.
999+
1. If _isLeap_ is *false*, then
1000+
1. Set _isLeap_ to *true*.
1001+
1. Else,
1002+
1. Set _isLeap_ to *false*.
1003+
1. Set _number_ to _number_ + 1.
1004+
1. Return ~invalid~.
10111005
</emu-alg>
10121006
</emu-clause>
10131007

@@ -1076,7 +1070,8 @@ contributors: Google, Ecma International
10761070
<h1>
10771071
RegulateNonISOYearMonth (
10781072
_calendar_: a calendar type that is not *"iso8601"*,
1079-
_isoDate_: an ISO Date Record,
1073+
_arithmeticalYear_: an integer,
1074+
_monthCode_: a String,
10801075
_years_: an integer,
10811076
): a Record with fields [[Year]] (an integer) and [[Month]] (an integer)
10821077
</h1>
@@ -1088,25 +1083,26 @@ contributors: Google, Ecma International
10881083
</dl>
10891084
<p>It performs the following steps when called:</p>
10901085
<emu-alg>
1091-
1. Let _y1_ be CalendarDateArithmeticYear(_calendar_, _isoDate_).
1092-
1. Let _d1_ be CalendarISOToDate(_calendar_, _isoDate_).
1093-
1. Let _monthCode_ be _d1_.[[MonthCode]].
1094-
1. Let _y2_ be _y1_ + _years_.
1086+
1. Let _y2_ be _arithmeticalYear_ + _years_.
10951087
1. If _calendar_ is *"chinese"*, *"dangi"*, or *"hebrew"*, then
10961088
1. If _calendar_ is *"chinese"* or *"dangi"*, then
1097-
1. If IsValidMonthCodeForCalendarInYear(_calendar_, _y2_, _monthCode_) is *false*, then
1098-
1. Set _monthCode_ to CreateMonthCode(ParseMonthCode(_monthCode_).[[Number]], *false*).
1089+
1. Let _month_ be MonthCodeToArithmeticalMonth(_calendar_, _y2_, _monthCode_).
1090+
1. If _month_ is ~invalid~, then
1091+
1. Let _monthCode_ be CreateMonthCode(ParseMonthCode(_monthCode_).[[Number]], *false*).
1092+
1. Set _month_ to MonthCodeToArithmeticalMonth(_calendar_, _y2_, _monthCode_).
1093+
1. Assert: _month_ is not ~invalid~.
10991094
1. Else,
11001095
1. Assert: _calendar_ is *"hebrew"*.
1101-
1. Let _d2_ be CalendarISOToDate(_calendar_, ! CalendarDateCodesToISO(_calendar_, _y2_, *"M01"*, 1)).
1102-
1. If _d1_.[[InLeapYear]] is *true* and _d2_.[[InLeapYear]] is *false*, then
1096+
1. Let _isLeap1_ be *true* if _arithmeticalYear_ is a leap year in the Hebrew calendar, or *false* otherwise.
1097+
1. Let _isLeap2_ be *true* if _y2_ is a leap year in the Hebrew calendar, or *false* otherwise.
1098+
1. If _isLeap1_ is *true* and _isLeap2_ is *false*, then
11031099
1. If _monthCode_ is *"M05L"*, then
11041100
1. Set _monthCode_ to *"M06"*.
1105-
1. Else if _d1_.[[InLeapYear]] is *false* and _d2_.[[InLeapYear]] is *true*, then
1101+
1. Else if _isLeap1_ is *false* and _isLeap2_ is *true*, then
11061102
1. If _monthCode_ is *"M06"*, then
11071103
1. Set _monthCode_ to *"M05L"*.
1108-
1. Assert: IsValidMonthCodeForCalendarInYear(_calendar_, _y2_, _monthCode_) is *true*.
1109-
1. Let _month_ be CalendarISOToDate(_calendar_, ! CalendarDateCodesToISO(_calendar_, _y2_, _monthCode_, 1)).[[Month]].
1104+
1. Let _month_ be MonthCodeToArithmeticalMonth(_calendar_, _monthCode_, _y2_).
1105+
1. Assert: _month_ is not ~invalid~.
11101106
1. Else,
11111107
1. Let _month_ be ParseMonthCode(_monthCode_).[[Number]].
11121108
1. Return the Record { [[Year]]: _y2_, [[Month]]: _month_ }.
@@ -1186,9 +1182,10 @@ contributors: Google, Ecma International
11861182
</dl>
11871183
<p>It performs the following steps when called:</p>
11881184
<emu-alg>
1189-
1. Let _yearMonth_ be RegulateNonISOYearMonth(_calendar_, _baseDate_, _years_).
1185+
1. Let _parts_ be CalendarISOToDate(_calendar_, _baseDate_).
1186+
1. Let _yearMonth_ be RegulateNonISOYearMonth(_calendar_, _parts_.[[Year]], _parts_.[[MonthCode]], _years_).
11901187
1. Let _endOfMonth_ be BalanceNonISODate(_calendar_, _yearMonth_.[[Year]], _yearMonth_.[[Month]] + _months_ + 1, 0).
1191-
1. Let _baseDay_ be CalendarISOToDate(_calendar_, _baseDate_).[[Day]].
1188+
1. Let _baseDay_ be _parts_.[[Day]].
11921189
1. If _weeks_ is not 0 or _days_ is not 0, then
11931190
1. If _baseDay_ &lt; _endOfMonth_.[[Day]], then
11941191
1. Let _regulatedDay_ be _baseDay_.
@@ -1282,16 +1279,31 @@ contributors: Google, Ecma International
12821279
<p>This definition supersedes the definition provided in <emu-xref href="#sec-temporal-nonisocalendardatetoiso"></emu-xref>.</p>
12831280
<p>It performs the following steps when called:</p>
12841281
<emu-alg>
1285-
1. If _fields_.[[Era]] and _fields_.[[EraYear]] are not ~unset~ and IsValidEraYearForCalendar(_calendar_, _fields_.[[Era]], _fields_.[[EraYear]]) is *false*, throw a *RangeError* exception.
1286-
1. If _fields_.[[MonthCode]] is not ~unset~ and IsValidMonthCodeForCalendar(_calendar_, _fields_.[[MonthCode]]) is *false*, throw a *RangeError* exception.
1287-
1. If _fields_ describes an existing date in _calendar_, return an implementation-defined ISO Date Record that corresponds to the date described by _fields_.
1288-
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
1289-
1. (This step only matters for lunisolar calendars.) If _fields_.[[MonthCode]] is a leap month that doesn't exist in the year, then:
1290-
1. Set _fields_ to another date according to the cultural conventions of that calendar's users. Of the currently supported calendars: if _calendar_ is *"chinese"* or *"dangi"*, change _fields_.[[MonthCode]] to the same month code but without the *"L"*. If _calendar_ is *"hebrew"*, change _fields_.[[MonthCode]] from *"M05L"* to *"M06"*.
1291-
1. Update _fields_.[[Month]] accordingly.
1292-
1. If _fields_.[[MonthCode]] is a valid month code for _fields_.[[Year]], but the date described by _fields_ does not exist, set _fields_.[[Day]] to the closest day in the same month. If there are two equally-close dates in the same month, pick the later one.
1293-
1. (This step does not apply to any currently supported calendars.) If the date described by _fields_ still does not exist, set _fields_ to the closest date in the same year. If there are two equally-close dates in that year, pick the later one.
1294-
1. Return an implementation-defined ISO Date Record that corresponds to the date described by _fields_.
1282+
1. If _fields_.[[Era]] and _fields_.[[EraYear]] are not ~unset~, then
1283+
1. If IsValidEraYearForCalendar(_calendar_, _fields_.[[Era]], _fields_.[[EraYear]]) is *false*, throw a *RangeError* exception.
1284+
1. Let _year_ be CalendarDateArithmeticYearForEraYear(_calendar_, _fields_.[[Era]], _fields_.[[EraYear]]).
1285+
1. Else,
1286+
1. Assert: _fields_.[[Year]] is not ~unset~.
1287+
1. Let _year_ be _fields_.[[Year]].
1288+
1. If _fields_.[[MonthCode]] is not ~unset~, then
1289+
1. If IsValidMonthCodeForCalendar(_calendar_, _fields_.[[MonthCode]]) is *false*, throw a *RangeError* exception.
1290+
1. If _overflow_ is ~reject~, then
1291+
1. Let _month_ be MonthCodeToArithmeticalMonth(_calendar_, _year_, _fields_.[[MonthCode]]).
1292+
1. If _month_ is ~invalid~, throw a *RangeError* exception.
1293+
1. Else,
1294+
1. Let _month_ be RegulateNonISOYearMonth(_calendar_, _year_, _monthCode_, 0).[[Month]].
1295+
1. Else,
1296+
1. Assert: _fields_.[[Month]] is not ~unset~.
1297+
1. Let _month_ be _fields_.[[Month]].
1298+
1. Let _day_ be _fields_.[[Day]].
1299+
1. Assert: _day_ is not ~unset~.
1300+
1. Let _daysInMonth_ be CalendarDaysInMonth(_calendar_, _year_, _month_).
1301+
1. If _daysInMonth_ &le; _day_, then
1302+
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
1303+
1. Let _regulatedDay_ be _daysInMonth_.
1304+
1. Else,
1305+
1. Let _regulatedDay_ be _day_.
1306+
1. Return ? CalendarDateArithmeticalToISO(_calendar_, _year_, _month_, _day_).
12951307
</emu-alg>
12961308
</emu-clause>
12971309

0 commit comments

Comments
 (0)