Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions biblio.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@
"type": "op",
"aoid": "ZeroDateDuration",
"id": "sec-temporal-zerodateduration"
},
{
"type": "op",
"aoid": "ParseMonthCode",
"id": "sec-temporal-parsemonthcode"
},
{
"type": "op",
"aoid": "CreateMonthCode",
"id": "sec-temporal-createmonthcode"
}
]
}
Expand Down
135 changes: 121 additions & 14 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -533,36 +533,135 @@ contributors: Google, Ecma International
<tr>
<th>Calendar</th>
<th>Additional Month Codes</th>
<th>Leap to Common Month Transformation</th>
</tr>
</thead>
<tr>
<td>*"chinese"*</td>
<td>*"M01L"*, *"M02L"*, *"M03L"*, *"M04L"*, *"M05L"*, *"M06L"*, *"M07L"*, *"M08L"*, *"M09L"*, *"M10L"*, *"M11L"*, *"M12L"*</td>
<td>~skip-backward~</td>
</tr>
<tr>
<td>*"coptic"*</td>
<td>*"M13"*</td>
<td></td>
</tr>
<tr>
<td>*"dangi"*</td>
<td>*"M01L"*, *"M02L"*, *"M03L"*, *"M04L"*, *"M05L"*, *"M06L"*, *"M07L"*, *"M08L"*, *"M09L"*, *"M10L"*, *"M11L"*, *"M12L"*</td>
<td>~skip-backward~</td>
</tr>
<tr>
<td>*"ethioaa"*</td>
<td>*"M13"*</td>
<td></td>
</tr>
<tr>
<td>*"ethiopic"*</td>
<td>*"M13"*</td>
<td></td>
</tr>
<tr>
<td>*"hebrew"*</td>
<td>*"M05L"*</td>
<td>~skip-forward~</td>
</tr>
</table>
</emu-table>
</emu-clause>

<emu-clause id="sec-temporal-yearcontainsmonthcode" type="implementation-defined abstract operation">
<h1>
YearContainsMonthCode (
_calendar_: a calendar type that is not *"iso8601"*,
_arithmeticYear_: an integer,
_monthCode_: a String,
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It returns whether the given _monthCode_ exists in _arithmeticYear_ of _calendar_.
</dd>
</dl>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Assert: IsValidMonthCodeForCalendar(_calendar_, _monthCode_) is *true*.
1. If ParseMonthCode(_monthCode_).[[IsLeap]] is *false*, return *true*.
1. Return whether the leap month indicated by _monthCode_ exists in the year _arithmeticYear_ in _calendar_, using calendar-dependent behaviour.
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-constrainmonthcode" type="abstract operation">
<h1>
ConstrainMonthCode (
_calendar_: a calendar type that is not *"iso8601"*,
_arithmeticYear_: an integer,
_monthCode_: a month code,
_overflow_: ~constrain~ or ~reject~,
): either a normal completion containing a month code or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It returns the month code in _arithmeticYear_ of _calendar_ that best matches the given _monthCode_. If _monthCode_ does not exist in _arithmeticYear_, it is constrained to the best common month if _overflow_ is ~constrain~, or an error is thrown if _overflow_ is ~reject~.
</dd>
</dl>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Assert: IsValidMonthCodeForCalendar(_calendar_, _monthCode_) is *true*.
1. If YearContainsMonthCode(_calendar_, _arithmeticYear_, _monthCode_) is *true*, return _monthCode_.
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
1. Assert: _calendar_ is listed in the Calendar column of <emu-xref href="#table-additional-month-codes"></emu-xref>.
1. Let _r_ be the row in <emu-xref href="#table-additional-month-codes"></emu-xref> which the _calendar_ is in the Calendar column.
1. Let _shiftType_ be the value given in the *"Leap to Common Month Transformation"* column of _r_.
1. If _shiftType_ is ~skip-backward~, then
1. Return CreateMonthCode(ParseMonthCode(_monthCode_).[[MonthNumber]], *false*).
1. Else,
1. Assert: _monthCode_ is *"M05L"*.
1. Return *"M06"*.
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-monthcodetoordinal" type="abstract operation">
<h1>
MonthCodeToOrdinal (
_calendar_: a calendar type that is not *"iso8601"*,
_arithmeticYear_: an integer,
_monthCode_: a month code,
): an integer
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It returns the ordinal month number for _monthCode_ in _arithmeticYear_ of _calendar_. The given _monthCode_ must exist in the given year.
</dd>
</dl>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Assert: YearContainsMonthCode(_calendar_, _arithmeticYear_, _monthCode_) is *true*.
1. Let _monthsBefore_ be 0.
1. Let _number_ be 1.
1. Let _isLeap_ be *false*.
1. Let _r_ be the row in <emu-xref href="#table-additional-month-codes"></emu-xref> which the _calendar_ is in the Calendar column.
1. If the *"Leap to Common Month Transformation"* column of _r_ is empty, then
1. Return ParseMonthCode(_monthCode_).[[MonthNumber]].
1. Assert: The *"Additional Month Codes"* column of _r_ does not contain *"M00L"* or *"M13"*.
1. Assert: The following loop will terminate.
1. Repeat, while _number_ &le; 12,
1. Let _currentMonthCode_ be CreateMonthCode(_number_, _isLeap_).
1. If YearContainsMonthCode(_calendar_, _arithmeticYear_, _currentMonthCode_), then
1. Set _monthsBefore_ to _monthsBefore_ + 1.
1. If _currentMonthCode_ is _monthCode_, then
1. Return _monthsBefore_.
1. If _isLeap_ is *false*, then
1. Set _isLeap_ to *true*.
1. Else,
1. Set _isLeap_ to *false*.
1. Set _number_ to _number_ + 1.
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-isvaliderayearforcalendar" type="abstract operation">
<h1>
IsValidEraYearForCalendar (
Expand Down Expand Up @@ -903,10 +1002,11 @@ contributors: Google, Ecma International
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _calendarDate_ be CalendarISOToDate(_calendar_, _isoDate_).
1. Add _duration_.[[Years]] to _calendarDate_.
1. (This step only matters for lunisolar calendars.) If _calendarDate_.[[MonthCode]] is a leap month that doesn't exist in the year, then:
1. Set _calendarDate_ 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 _calendarDate_.[[MonthCode]] to the same month code but without the *"L"*. If _calendar_ is *"hebrew"*, change _calendarDate_.[[MonthCode]] from *"M05L"* to *"M06"*.
1. Update _calendarDate_.[[Month]] accordingly.
1. Add _duration_.[[Years]] to _calendarDate_ without changing any less-significant fields.
1. If YearContainsMonthCode(_calendar_, _calendarDate_.[[Year]], _calendarDate_.[[MonthCode]]) is *false*, then
1. NOTE: This only happens in lunisolar calendars.
1. Set _calendarDate_.[[MonthCode]] to ! ConstrainMonthCode(_calendar_, _calendarDate_.[[Year]], _calendarDate_.[[MonthCode]], ~constrain~).
1. Set _calendarDate_.[[Month]] to MonthCodeToOrdinal(_calendar_, _calendarDate_.[[Year]], _calendarDate_.[[MonthCode]]).
1. Add _duration_.[[Months]] to _calendarDate_, balancing _calendarDate_ if it goes over a year boundary.
1. If the date described by _calendarDate_ does not exist, then
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
Expand Down Expand Up @@ -972,16 +1072,23 @@ contributors: Google, Ecma International
<p>This definition supersedes the definition provided in <emu-xref href="#sec-temporal-nonisocalendardatetoiso"></emu-xref>.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. If _fields_.[[Era]] and _fields_.[[EraYear]] are not ~unset~ and IsValidEraYearForCalendar(_calendar_, _fields_.[[Era]], _fields_.[[EraYear]]) is *false*, throw a *RangeError* exception.
1. If _fields_.[[MonthCode]] is not ~unset~ and IsValidMonthCodeForCalendar(_calendar_, _fields_.[[MonthCode]]) is *false*, throw a *RangeError* exception.
1. If _fields_ describes an existing date in _calendar_, return an implementation-defined ISO Date Record that corresponds to the date described by _fields_.
1. If _overflow_ is ~reject~, throw a *RangeError* exception.
1. (This step only matters for lunisolar calendars.) If _fields_.[[MonthCode]] is a leap month that doesn't exist in the year, then:
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"*.
1. Update _fields_.[[Month]] accordingly.
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.
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.
1. Return an implementation-defined ISO Date Record that corresponds to the date described by _fields_.
1. If _fields_.[[Era]] and _fields_.[[EraYear]] are not ~unset~, then
1. If IsValidEraYearForCalendar(_calendar_, _fields_.[[Era]], _fields_.[[EraYear]]) is *false*, throw a *RangeError* exception.
1. Let _arithmeticYear_ be CalendarDateArithmeticYearForEraYear(_calendar_, _fields_.[[Era]], _fields_.[[EraYear]]).
1. Else,
1. Assert: _fields_.[[Year]] is not ~unset~.
1. Let _arithmeticYear_ be _fields_.[[Year]].
1. If _fields_.[[MonthCode]] is not ~unset~, then
1. If IsValidMonthCodeForCalendar(_calendar_, _fields_.[[MonthCode]]) is *false*, throw a *RangeError* exception.
1. Let _constrainedMonthCode_ be ? ConstrainMonthCode(_calendar_, _arithmeticYear_, _fields_.[[MonthCode]], _overflow_).
1. Let _ordinalMonth_ be MonthCodeToOrdinal(_calendar_, _arithmeticYear_, _constrainedMonthCode_).
1. Else,
1. Assert: _fields_.[[Month]] is not ~unset~.
1. Let _ordinalMonth_ be _fields_.[[Month]].
1. Let _day_ be _fields_.[[Day]].
1. Assert: _day_ is not ~unset~.
1. If the date described by _calendar_, _arithmeticYear_, _ordinalMonth_, and _day_ does not exist, set _day_ to the closest day in the same month. If there are two equally-close dates in the same month, pick the later one.
1. Return an implementation-defined ISO Date Record that corresponds to the date described by _calendar_, _arithmeticYear_, _ordinalMonth_, and _day_.
</emu-alg>
</emu-clause>

Expand Down