Stage 2 Draft / February 7, 2023

Intl era and monthCode Proposal

1 Abstract Operations for Temporal.Calendar Objects

1.1 IsCalendarSupportEra ( calendar )

The abstract operation IsCalendarSupportEra takes argument calendar (a String) and returns a Boolean. The following algorithm refers to the era data from UTS 35's Supplemental Calendar Data. It performs the following steps when called:

  1. If calendar is listed in the Calendar column of Table 1, return true.
  2. Return false.
Table 1: era aliases and range of eraYear
Calendar Era Aliases Minimum eraYear Maximum eraYear
"buddhist" "buddhist" "be" -∞𝔽 +∞𝔽
"chinese" "chinese" -∞𝔽 +∞𝔽
"coptic" "coptic" 1𝔽 +∞𝔽
"coptic" "coptic-inverse" 1𝔽 +∞𝔽
"dangi" "dangi" -∞𝔽 +∞𝔽
"ethiopic" "ethiopic" "incar" 1𝔽 +∞𝔽
"ethiopic" "ethiopicaa" "ethiopic-amete-alem", "mundi" -∞𝔽 5500𝔽
"ethiopicaa" "ethiopicaa" "ethiopic-amete-alem", "mundi" -∞𝔽 +∞𝔽
"gregory" "gregory" "ce", "ad" 1𝔽 +∞𝔽
"gregory" "gregory-inverse" "bc", "bce" 1𝔽 +∞𝔽
"hebrew" "hebrew" "am" -∞𝔽 +∞𝔽
"indian" "indian" "saka" -∞𝔽 +∞𝔽
"islamic" "islamic" "ah" -∞𝔽 +∞𝔽
"islamic-civil" "islamic-civil" "islamicc", "ah" -∞𝔽 +∞𝔽
"islamic-rgsa" "islamic-rgsa" "ah" -∞𝔽 +∞𝔽
"islamic-tbla" "islamic-tbla" "ah" -∞𝔽 +∞𝔽
"islamic-umalqura" "islamic-umalqura" "ah" -∞𝔽 +∞𝔽
"japanese" "heisei" 1𝔽 31𝔽
"japanese" "japanese" "gregory", "ad", "ce" 1𝔽 1868𝔽
"japanese" "japanese-inverse" "gregory-inverse", "bc", "bce" 1𝔽 +∞𝔽
"japanese" "meiji" 1𝔽 45𝔽
"japanese" "reiwa" 1𝔽 +∞𝔽
"japanese" "showa" 1𝔽 64𝔽
"japanese" "taisho" 1𝔽 15𝔽
"persian" "persian" "ap" -∞𝔽 +∞𝔽
"roc" "roc" "minguo"* 1𝔽 +∞𝔽
"roc" "roc-inverse" "before-roc" 1𝔽 +∞𝔽
Note
The content in this table is proposed by Era Code WG to CLDR TC in PR 2665 and under review. It is targeted to be part of CLDR 43, scheduled to be released in April 2023.

1.2 CanonicalizeEraInCalendar ( calendar, era )

The abstract operation CanonicalizeEraInCalendar takes arguments calendar (a String) and era (a String) and returns a String or undefined. The following algorithm refers to the era data from UTS 35's Supplemental Calendar Data. It performs the following steps when called:

  1. For each row of Table 1, do
    1. Let cal be the Calendar value of the current row.
    2. If cal is equal to calendar, then
      1. Let e be the Era value of the current row.
      2. If e is equal to era, return era.
      3. Let aliases be a List whose elements are the strings given in the Aliases column of the row.
      4. If aliases contains era, return era.
  2. Return undefined.

1.3 IsValidMonthCodeForCalendar ( calendar, monthCode )

The abstract operation IsValidMonthCodeForCalendar takes arguments calendar (a String) and monthCode (a String) and returns a Boolean. It performs the following steps when called:

  1. Let commonMonthCodes be « "M01", "M02", "M03", "M04", "M05", "M06", "M07", "M08", "M09", "M10", "M11", "M12" ».
  2. If commonMonthCodes contains monthCode, return true.
  3. If calendar is not listed in the Calendar column of Table 2, return false.
  4. Let r be the row in Table 2 which the clendar is in the Calendar column.
  5. Let specialMonthCodes be a List whose elements are the strings given in the "Additional Month Codes" column of r.
  6. If specialMonthCodes contains monthCode, return true.
  7. Return false.
Table 2: Additional Month Codes in Calendars
Calendar Additional Month Codes
"chinese" "M01L", "M02L", "M03L", "M04L", "M05L", "M06L", "M07L", "M08L", "M09L", "M10L", "M11L", "M12L"
"coptic" "M13"
"dangi" "M01L", "M02L", "M03L", "M04L", "M05L", "M06L", "M07L", "M08L", "M09L", "M10L", "M11L", "M12L"
"ethiopic" "M13"
"ethiopicaa" "M13"
"hebrew" "M05L"

1.4 IsValidEraYearForCalendar ( calendar, era, eraYear )

The abstract operation IsValidEraYearForCalendar takes arguments calendar (a String), era (a String), and eraYear (a integer) and returns a Boolean. The following algorithm refers to the era data from UTS 35's Supplemental Calendar Data. It performs the following steps when called:

  1. Let era be CanonicalizeEraInCalendar(calendar, era).
  2. If era is undefined, return false.
  3. Let r be the row in Table 1 which the calendar is in the Calendar column and the era is in the Era column.
  4. Let min be the value given in the "Minimum eraYear" column of r.
  5. Let max be the value given in the "Maximum eraYear" column of r.
  6. If eraYear < min, return false.
  7. If eraYear > max, return false.
  8. Return true.

1.5 CalendarDateEra ( calendar, date )

The abstract operation CalendarDateEra takes arguments calendar (a String) and date (a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth) and returns a String or undefined. It performs implementation-defined processing to find the era for the date corresponding to date in the context of the calendar represented by calendar and returns a lowercase String value representing that era, or undefined for calendars that do not have eras.

This definition supersedes the definition provided in "Temporal proposal", #sec-temporal-calendardateera.

  1. If IsCalendarSupportEra(calendar) is false, return undefined.
  2. Let era be the String to indicate the era corresponding to date in the context of the calendar represented by calendar from an implementation-defined processing.
  3. Return CanonicalizeEraInCalendar(calendar, era).

1.6 CalendarDateEraYear ( calendar, date )

The abstract operation CalendarDateEraYear takes arguments calendar (a String) and date (a Temporal.PlainDateTime, Temporal.PlainDate, or Temporal.PlainYearMonth) and returns an integer or undefined. It performs implementation-defined processing to find the era for the date corresponding to date in the context of the calendar represented by calendar and returns an integer representing the ordinal position of the year of date in that era, or undefined for calendars that do not have eras.

This definition supersedes the definition provided in "Temporal proposal", #sec-temporal-calendardateerayear.

  1. If IsCalendarSupportEra(calendar) is false, return undefined.
  2. Let eraYear be the integer to indicate the era year corresponding to date in the context of the calendar represented by calendar from an implementation-defined processing.
  3. Assert: eraYear is an integer.
  4. Return eraYear.
Note
Era years are 1-indexed for many calendars, but not all (e.g., the eras of the Burmese calendar each start with a year 0). Years can also advance opposite the flow of time (as for BCE years in the Gregorian calendar).

1.7 CalendarDateFields ( calendar, fields )

The abstract operation CalendarDateFields takes arguments calendar (a String) and fields (a List of Strings) and returns a List of Strings. It takes a list of standard fields in fields that are necessary for a given operation and returns a new list by adding relevant calendar-specific fields for the calendar represented by calendar. This is relevant for calendars which accept fields other than the standard set of built-in calendar fields.

This definition supersedes the definition provided in "Temporal proposal", #sec-temporal-calendardatefields.

  1. If fields contains an element equal to "year" and IsCalendarSupportEra(calendar) is true, then
    1. Append "era" to fields.
    2. Append "eraYear" to fields.
  2. Return fields.

1.8 CalendarDateMergeFields ( calendar, fields, additionalFields )

The abstract operation CalendarDateMergeFields takes arguments calendar (a String), fields (an Object), and additionalFields (an Object) and returns either a normal completion containing an Object or an abrupt completion. It takes two Objects of calendar-specific fields for the calendar represented by calendar in fields and additionalFields and returns a new Object that includes both sets of fields. The values in additionalFields should supersede the values in fields. Also, the returned Object must be free of ambiguity or conflicts. This is relevant for calendars which accept fields other than the standard set of built-in calendar fields.

This definition supersedes the definition provided in "Temporal proposal", #sec-temporal-calendardatemergefields.

Note
For example, if fields contains "year" but additionalFields contains "era" and "eraYear", then the returned list must not include "year" in order to avoid ambiguity or conflict between different ways of specifying the year.
  1. Let handleEra be IsCalendarSupportEra(calendar).
  2. Let merged be OrdinaryObjectCreate(%Object.prototype%).
  3. Let fieldsKeys be ? EnumerableOwnPropertyNames(fields, key).
  4. For each element key of fieldsKeys, do
    1. If key is not "month" or "monthCode", then
      1. If handlEra is false or key is not "era", "eraYear" or "year", then
        1. Let propValue be ? Get(fields, key).
        2. If propValue is not undefined, then
          1. Perform ! CreateDataPropertyOrThrow(merged, key, propValue).
  5. Let additionalFieldsKeys be ? EnumerableOwnPropertyNames(additionalFields, key).
  6. For each element key of additionalFieldsKeys, do
    1. Let propValue be ? Get(additionalFields, key).
    2. If propValue is not undefined, then
      1. Perform ! CreateDataPropertyOrThrow(merged, key, propValue).
  7. If additionalFieldsKeys does not contain either "month" or "monthCode", then
    1. Let month be ? Get(fields, "month").
    2. If month is not undefined, then
      1. Perform ! CreateDataPropertyOrThrow(merged, "month", month).
    3. Let monthCode be ? Get(fields, "monthCode").
    4. If monthCode is not undefined, then
      1. Perform ! CreateDataPropertyOrThrow(merged, "monthCode", monthCode).
  8. If handleEra is true, then
    1. If additionalFieldsKeys does not contain "era", "eraYear", or "year", then
      1. Let year be ? Get(fields, "year").
      2. If year is not undefined, then
        1. Perform ! CreateDataPropertyOrThrow(merged, "year", year).
  9. Return merged.

A Copyright & Software License

Copyright Notice

© 2023 Google, Ecma International

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.