Amendments to the ECMAScript® 2023 Internationalization API Specification

This section lists amendments which must be made to ECMA-402, the ECMAScript® 2023 Internationalization API Specification. Text to be added is marked like this, and text to be deleted is marked like this. Blocks of unmodified text between modified sections are marked by [...].

This text is based on top of the ECMA-402 spec text from commit 537afda7be28a443b79b3fd7e6c836a16ce4f75f.

Case Sensitivity and Case Mapping

These definitions are moved into ECMA-262.

The String values used to identify locales, currencies, scripts, and time zones are interpreted in an ASCII-case-insensitive manner, treating the code units 0x0041 through 0x005A (corresponding to Unicode characters LATIN CAPITAL LETTER A through LATIN CAPITAL LETTER Z) as equivalent to the corresponding code units 0x0061 through 0x007A (corresponding to Unicode characters LATIN SMALL LETTER A through LATIN SMALL LETTER Z), both inclusive. No other case folding equivalences are applied.

For example, *"ß"* (U+00DF) must not match or be mapped to *"SS"* (U+0053, U+0053). *"ı"* (U+0131) must not match or be mapped to *"I"* (U+0049).

The ASCII-uppercase of a String value _S_ is the String value derived from _S_ by replacing each occurrence of an ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive) with the corresponding ASCII uppercase letter code unit (0x0041 through 0x005A, inclusive) while preserving all other code units.

The ASCII-lowercase of a String value _S_ is the String value derived from _S_ by replacing each occurrence of an ASCII uppercase letter code unit (0x0041 through 0x005A, inclusive) with the corresponding ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive) while preserving all other code units.

A String value _A_ is an ASCII-case-insensitive match for String value _B_ if the ASCII-uppercase of _A_ is exactly the same sequence of code units as the ASCII-uppercase of _B_. A sequence of Unicode code points _A_ is an ASCII-case-insensitive match for _B_ if _B_ is an ASCII-case-insensitive match for ! CodePointsToString(_A_).

Calendar Types

This specification identifies calendars using a calendar type as defined by Unicode Technical Standard #35 Part 4 Dates, Section 2 Calendar Elements. Their canonical form is a string containing only Unicode Basic Latin lowercase letters (U+0061 LATIN SMALL LETTER A through U+007A LATIN SMALL LETTER Z) with zero or more medial hyphens (U+002D HYPHEN-MINUS).

AvailableCalendars ( ): a List of Strings

description
The returned List is sorted according to lexicographic code unit order, and contains unique calendar types in canonical form () identifying the calendars for which the implementation provides the functionality of Intl.DateTimeFormat objects, including their aliases (e.g., either both or neither of *"islamicc"* and *"islamic-civil"*). The List must include *"iso8601"*.
redefinition
true

Abstract Operations

In this section, some abstract operations that manipulate options objects are to be moved from ECMA-402 into ECMA-262.

GetOptionsObject ( _options_: an ECMAScript language value, ): either a normal completion containing an Object or a throw completion

description
It returns an Object suitable for use with GetOption, either _options_ itself or a default empty Object. It throws a *TypeError* if _options_ is not *undefined* and not an Object.
redefinition
true
1. If _options_ is *undefined*, then 1. Return OrdinaryObjectCreate(*null*). 1. If Type(_options_) is Object, then 1. Return _options_. 1. Throw a *TypeError* exception.

[...]

GetOption ( _options_: an Object, _property_: a property key, _type_: ~boolean~ or ~string~, _values_: ~empty~ or a List of ECMAScript language values, _default_: ~required~ or an ECMAScript language value, ): either a normal completion containing an ECMAScript language value or a throw completion

description
It extracts the value of the specified property of _options_, converts it to the required _type_, checks whether it is allowed by _values_ if _values_ is not ~empty~, and substitutes _default_ if the value is *undefined*.
redefinition
true
1. Let _value_ be ? Get(_options_, _property_). 1. If _value_ is *undefined*, then 1. If _default_ is ~required~, throw a *RangeError* exception. 1. Return _default_. 1. If _type_ is ~boolean~, then 1. Set _value_ to ToBoolean(_value_). 1. Else, 1. Assert: _type_ is ~string~. 1. Set _value_ to ? ToString(_value_). 1. If _values_ is not ~empty~ and _values_ does not contain _value_, throw a *RangeError* exception. 1. Return _value_.

[...]

Rounding modes in Intl.NumberFormat
Identifier Description Examples: Round to 0 fraction digits
-1.5 0.4 0.5 0.6 1.5
*"ceil"* Toward positive infinity ⬆️ [-1] ⬆️ [1] ⬆️ [1] ⬆️ [1] ⬆️ [2]
*"floor"* Toward negative infinity ⬇️ [-2] ⬇️ [0] ⬇️ [0] ⬇️ [0] ⬇️ [1]
*"expand"* Away from zero ⬇️ [-2] ⬆️ [1] ⬆️ [1] ⬆️ [1] ⬆️ [2]
*"trunc"* Toward zero ⬆️ [-1] ⬇️ [0] ⬇️ [0] ⬇️ [0] ⬇️ [1]
*"halfCeil"* Ties toward positive infinity ⬆️ [-1] ⬇️ [0] ⬆️ [1] ⬆️ [1] ⬆️ [2]
*"halfFloor"* Ties toward negative infinity ⬇️ [-2] ⬇️ [0] ⬇️ [0] ⬆️ [1] ⬇️ [1]
*"halfExpand"* Ties away from zero ⬇️ [-2] ⬇️ [0] ⬆️ [1] ⬆️ [1] ⬆️ [2]
*"halfTrunc"* Ties toward zero ⬆️ [-1] ⬇️ [0] ⬇️ [0] ⬆️ [1] ⬇️ [1]
*"halfEven"* Ties toward an even rounding increment multiple ⬇️ [-2] ⬇️ [0] ⬇️ [0] ⬆️ [1] ⬆️ [2]
The examples are illustrative of the unique behaviour of each option. ⬆️ means "resolves toward positive infinity"; ⬇️ means "resolves toward negative infinity".

GetUnsignedRoundingMode ( _roundingMode_: a String, _sign_: ~negative~ or ~positive~, ): a specification type from the Unsigned Rounding Mode column of

description
It returns the rounding mode that should be applied to the absolute value of a number to produce the same result as if _roundingMode_, one of the String values in the Identifier column of , were applied to the signed value of the number (negative if _sign_ is ~negative~, or positive otherwise).
redefinition
true
1. Return the specification type in the Unsigned Rounding Mode column of for the row where the value in the Identifier column is _roundingMode_ and the value in the Sign column is _sign_. Conversion from rounding mode to unsigned rounding mode
Identifier Sign Unsigned Rounding Mode
*"ceil"* ~positive~ ~infinity~
~negative~ ~zero~
*"floor"* ~positive~ ~zero~
~negative~ ~infinity~
*"expand"* ~positive~ ~infinity~
~negative~ ~infinity~
*"trunc"* ~positive~ ~zero~
~negative~ ~zero~
*"halfCeil"* ~positive~ ~half-infinity~
~negative~ ~half-zero~
*"halfFloor"* ~positive~ ~half-zero~
~negative~ ~half-infinity~
*"halfExpand"* ~positive~ ~half-infinity~
~negative~ ~half-infinity~
*"halfTrunc"* ~positive~ ~half-zero~
~negative~ ~half-zero~
*"halfEven"* ~positive~ ~half-even~
~negative~ ~half-even~

ApplyUnsignedRoundingMode ( _x_: a mathematical value, _r1_: a mathematical value, _r2_: a mathematical value, _unsignedRoundingMode_: a specification type from the Unsigned Rounding Mode column of , or *undefined*, ): a mathematical value

description
It considers _x_, bracketed below by _r1_ and above by _r2_, and returns either _r1_ or _r2_ according to _unsignedRoundingMode_.
redefinition
true
1. If _x_ is equal to _r1_, return _r1_. 1. Assert: _r1_ < _x_ < _r2_. 1. Assert: _unsignedRoundingMode_ is not *undefined*. 1. If _unsignedRoundingMode_ is ~zero~, return _r1_. 1. If _unsignedRoundingMode_ is ~infinity~, return _r2_. 1. Let _d1_ be _x_ – _r1_. 1. Let _d2_ be _r2_ – _x_. 1. If _d1_ < _d2_, return _r1_. 1. If _d2_ < _d1_, return _r2_. 1. Assert: _d1_ is equal to _d2_. 1. If _unsignedRoundingMode_ is ~half-zero~, return _r1_. 1. If _unsignedRoundingMode_ is ~half-infinity~, return _r2_. 1. Assert: _unsignedRoundingMode_ is ~half-even~. 1. Let _cardinality_ be (_r1_ / (_r2_ – _r1_)) modulo 2. 1. If _cardinality_ is 0, return _r1_. 1. Return _r2_.

The Intl.DateTimeFormat Constructor

[...]

CreateDateTimeFormat ( _newTarget_: a constructor, _locales_: an ECMAScript language value, _options_: an ECMAScript language value, _required_: ~date~, ~time~, or ~any~, _defaults_: ~date~, ~time~, or ~all~, optional _toLocaleStringTimeZone_: a primary time zone identifier, ): either a normal completion containing a DateTimeFormat object or a throw completion

description
If the additional _toLocaleStringTimeZone_ argument is provided, the time zone will be overridden and some adjustments will be made to the defaults in order to implement the behaviour of `Temporal.ZonedDateTime.prototype.toLocaleString`.
1. Let _dateTimeFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%Intl.DateTimeFormat.prototype%"*, « [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[HourCycle]], [[DateStyle]], [[TimeStyle]], [[DateTimeFormat]], [[TemporalPlainDateFormat]], [[TemporalPlainYearMonthFormat]], [[TemporalPlainMonthDayFormat]], [[TemporalPlainTimeFormat]], [[TemporalPlainDateTimeFormat]], [[TemporalInstantFormat]], [[BoundFormat]] »). 1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_). 1. Set _options_ to ? CoerceOptionsToObject(_options_). 1. Let _opt_ be a new Record. 1. Let _matcher_ be ? GetOption(_options_, *"localeMatcher"*, ~string~, « *"lookup"*, *"best fit"* », *"best fit"*). 1. Set _opt_.[[localeMatcher]] to _matcher_. 1. Let _calendar_ be ? GetOption(_options_, *"calendar"*, ~string~, ~empty~, *undefined*). 1. If _calendar_ is not *undefined*, then 1. If _calendar_ cannot be matched by the type Unicode locale nonterminal, throw a *RangeError* exception. 1. Set _opt_.[[ca]] to _calendar_. 1. Let _numberingSystem_ be ? GetOption(_options_, *"numberingSystem"*, ~string~, ~empty~, *undefined*). 1. If _numberingSystem_ is not *undefined*, then 1. If _numberingSystem_ cannot be matched by the type Unicode locale nonterminal, throw a *RangeError* exception. 1. Set _opt_.[[nu]] to _numberingSystem_. 1. Let _hour12_ be ? GetOption(_options_, *"hour12"*, ~boolean~, ~empty~, *undefined*). 1. Let _hourCycle_ be ? GetOption(_options_, *"hourCycle"*, ~string~, « *"h11"*, *"h12"*, *"h23"*, *"h24"* », *undefined*). 1. If _hour12_ is not *undefined*, then 1. Set _hourCycle_ to *null*. 1. Set _opt_.[[hc]] to _hourCycle_. 1. Let _r_ be ResolveLocale(%Intl.DateTimeFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %Intl.DateTimeFormat%.[[RelevantExtensionKeys]], %Intl.DateTimeFormat%.[[LocaleData]]). 1. Set _dateTimeFormat_.[[Locale]] to _r_.[[Locale]]. 1. Let _resolvedCalendar_ be _r_.[[ca]]. 1. Set _dateTimeFormat_.[[Calendar]] to _resolvedCalendar_. 1. Set _dateTimeFormat_.[[NumberingSystem]] to _r_.[[nu]]. 1. Let _resolvedLocaleData_ be _r_.[[LocaleData]]. 1. If _hour12_ is *true*, then 1. Let _hc_ be _resolvedLocaleData_.[[hourCycle12]]. 1. Else if _hour12_ is *false*, then 1. Let _hc_ be _resolvedLocaleData_.[[hourCycle24]]. 1. Else, 1. Assert: _hour12_ is *undefined*. 1. Let _hc_ be _r_.[[hc]]. 1. If _hc_ is *null*, set _hc_ to _resolvedLocaleData_.[[hourCycle]]. 1. Set _dateTimeFormat_.[[HourCycle]] to _hc_. 1. Let _timeZone_ be ? Get(_options_, *"timeZone"*). 1. If _timeZone_ is *undefined*, then 1. If _toLocaleStringTimeZone_ is present, then 1. Set _timeZone_ to _toLocaleStringTimeZone_. 1. Else, 1. Set _timeZone_ to SystemTimeZoneIdentifier(). 1. Else, 1. If _toLocaleStringTimeZone_ is present, throw a *TypeError* exception. 1. Set _timeZone_ to ? ToString(_timeZone_). 1. If IsTimeZoneOffsetString(_timeZone_) is *true*, then 1. Let _parseResult_ be ParseText(StringToCodePoints(_timeZone_), |UTCOffset||UTCOffset[~SubMinutePrecision]|). 1. Assert: _parseResult_ is a Parse Node. 1. If _parseResult_ contains more than one |MinuteSecond| Parse Node, throw a *RangeError* exception. 1. Let _offsetNanoseconds_ be ParseTimeZoneOffsetString? ParseDateTimeUTCOffset(_timeZone_). 1. Let _offsetMinutes_ be _offsetNanoseconds_ / (6 × 1010). 1. Assert: _offsetMinutes_ is an integer. 1. Set _timeZone_ to FormatOffsetTimeZoneIdentifier(_offsetMinutes_). 1. Else if IsValidTimeZoneName(_timeZone_) is *true*, then 1. Else, 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_timeZone_). 1. If _timeZoneIdentifierRecord_ is ~empty~, then 1. Throw a *RangeError* exception. 1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_)_timeZoneIdentifierRecord_.[[Identifier]]. 1. Else, 1. Throw a *RangeError* exception. 1. Set _dateTimeFormat_.[[TimeZone]] to _timeZone_. 1. Let _formatOptions_ be a new Record. 1. Set _formatOptions_.[[hourCycle]] to _hc_. 1. Let _hasExplicitFormatComponents_ be *false*. 1. For each row of , except the header row, in table order, do 1. Let _prop_ be the name given in the Property column of the row. 1. If _prop_ is *"fractionalSecondDigits"*, then 1. Let _value_ be ? GetNumberOption(_options_, *"fractionalSecondDigits"*, 1, 3, *undefined*). 1. Else, 1. Let _values_ be a List whose elements are the strings given in the Values column of the row. 1. Let _value_ be ? GetOption(_options_, _prop_, ~string~, _values_, *undefined*). 1. Set _formatOptions_.[[<_prop_>]] to _value_. 1. If _value_ is not *undefined*, then 1. Set _hasExplicitFormatComponents_ to *true*. 1. Let _formatMatcher_ be ? GetOption(_options_, *"formatMatcher"*, ~string~, « *"basic"*, *"best fit"* », *"best fit"*). 1. Let _dateStyle_ be ? GetOption(_options_, *"dateStyle"*, ~string~, « *"full"*, *"long"*, *"medium"*, *"short"* », *undefined*). 1. Set _dateTimeFormat_.[[DateStyle]] to _dateStyle_. 1. Let _timeStyle_ be ? GetOption(_options_, *"timeStyle"*, ~string~, « *"full"*, *"long"*, *"medium"*, *"short"* », *undefined*). 1. Set _dateTimeFormat_.[[TimeStyle]] to _timeStyle_. 1. Let _formats_ be _resolvedLocaleData_.[[formats]].[[<_resolvedCalendar_>]]. 1. If _dateStyle_ is not *undefined* or _timeStyle_ is not *undefined*, then 1. If _hasExplicitFormatComponents_ is *true*, then 1. Throw a *TypeError* exception. 1. If _required_ is ~date~ and _timeStyle_ is not *undefined*, then 1. Throw a *TypeError* exception. 1. If _required_ is ~time~ and _dateStyle_ is not *undefined*, then 1. Throw a *TypeError* exception. 1. Let _styles_ be _resolvedLocaleData_.[[styles]].[[<_resolvedCalendar_>]]. 1. Let _bestFormat_ be DateTimeStyleFormat(_dateStyle_, _timeStyle_, _styles_). 1. If _dateStyle_ is not *undefined*, then 1. Set _dateTimeFormat_.[[TemporalPlainDateFormat]] to AdjustDateTimeStyleFormat(_formats_, _bestFormat_, _formatMatcher_, « [[weekday]], [[era]], [[year]], [[month]], [[day]] »). 1. Set _dateTimeFormat_.[[TemporalPlainYearMonthFormat]] to AdjustDateTimeStyleFormat(_formats_, _bestFormat_, _formatMatcher_, « [[era]], [[year]], [[month]] »). 1. Set _dateTimeFormat_.[[TemporalPlainMonthDayFormat]] to AdjustDateTimeStyleFormat(_formats_, _bestFormat_, _formatMatcher_, « [[month]], [[day]] »). 1. Else, 1. Set _dateTimeFormat_.[[TemporalPlainDateFormat]] to *null*. 1. Set _dateTimeFormat_.[[TemporalPlainYearMonthFormat]] to *null*. 1. Set _dateTimeFormat_.[[TemporalPlainMonthDayFormat]] to *null*. 1. If _timeStyle_ is not *undefined*, then 1. Set _dateTimeFormat_.[[TemporalPlainTimeFormat]] to AdjustDateTimeStyleFormat(_formats_, _bestFormat_, _formatMatcher_, « [[dayPeriod]], [[hour]], [[minute]], [[second]], [[fractionalSecondDigits]] »). 1. Else, 1. Set _dateTimeFormat_.[[TemporalPlainTimeFormat]] to *null*. 1. Set _dateTimeFormat_.[[TemporalPlainDateTimeFormat]] to AdjustDateTimeStyleFormat(_formats_, _bestFormat_, _formatMatcher_, « [[weekday]], [[era]], [[year]], [[month]], [[day]], [[dayPeriod]], [[hour]], [[minute]], [[second]], [[fractionalSecondDigits]] »). 1. Set _dateTimeFormat_.[[TemporalInstantFormat]] to _bestFormat_. 1. Else, 1. Let _needDefaults_ be *true*. 1. If _required_ is ~date~ or ~any~, then 1. For each property name _prop_ of « *"weekday"*, *"year"*, *"month"*, *"day"* », do 1. Let _value_ be _formatOptions_.[[<_prop_>]]. 1. If _value_ is not *undefined*, set _needDefaults_ to *false*. 1. If _required_ is ~time~ or ~any~, then 1. For each property name _prop_ of « *"dayPeriod"*, *"hour"*, *"minute"*, *"second"*, *"fractionalSecondDigits"* », do 1. Let _value_ be _formatOptions_.[[<_prop_>]]. 1. If _value_ is not *undefined*, set _needDefaults_ to *false*. 1. If _needDefaults_ is *true* and _defaults_ is either ~date~ or ~all~, then 1. For each property name _prop_ of « *"year"*, *"month"*, *"day"* », do 1. Set _formatOptions_.[[<_prop_>]] to *"numeric"*. 1. If _needDefaults_ is *true* and _defaults_ is either ~time~ or ~all~, then 1. For each property name _prop_ of « *"hour"*, *"minute"*, *"second"* », do 1. Set _formatOptions_.[[<_prop_>]] to *"numeric"*. 1. Let _formats_ be _resolvedLocaleData_.[[formats]].[[<_resolvedCalendar_>]]. 1. If _formatMatcher_ is *"basic"*, then 1. Let _bestFormat_ be BasicFormatMatcher(_formatOptions_, _formats_). 1. Else, 1. Let _bestFormat_ be BestFitFormatMatcher(_formatOptions_, _formats_). 1. Let _bestFormat_ be GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, _required_, _defaults_, ~all~). 1. Set _dateTimeFormat_.[[TemporalPlainDateFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~date~, ~date~, ~relevant~). 1. Set _dateTimeFormat_.[[TemporalPlainYearMonthFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~year-month~, ~year-month~, ~relevant~). 1. Set _dateTimeFormat_.[[TemporalPlainMonthDayFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~month-day~, ~month-day~, ~relevant~). 1. Set _dateTimeFormat_.[[TemporalPlainTimeFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~time~, ~time~, ~relevant~). 1. Set _dateTimeFormat_.[[TemporalPlainDateTimeFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~any~, ~all~, ~relevant~). 1. If _toLocaleStringTimeZone_ is present, then 1. Set _dateTimeFormat_.[[TemporalInstantFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~any~, ~zoned-date-time~, ~all~). 1. Else, 1. Set _dateTimeFormat_.[[TemporalInstantFormat]] to GetDateTimeFormat(_formats_, _formatMatcher_, _formatOptions_, ~any~, ~all~, ~all~). 1. Set _dateTimeFormat_.[[DateTimeFormat]] to _bestFormat_. 1. If _bestFormat_ has a field [[hour]], then 1. Set _dateTimeFormat_.[[HourCycle]] to _hc_. 1. Return _dateTimeFormat_.

Properties of the Intl.DateTimeFormat Constructor

[...]

Internal slots

[...]

The value of the [[LocaleData]] internal slot is implementation-defined within the constraints described in and the following additional constraints, for all locale values _locale_:

  • [[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values *"native"*, *"traditio"*, or *"finance"*.
  • [[LocaleData]].[[<_locale_>]].[[hc]] must be « *null*, *"h11"*, *"h12"*, *"h23"*, *"h24"* ».
  • [[LocaleData]].[[<_locale_>]].[[hourCycle]] must be one of the String values *"h11"*, *"h12"*, *"h23"*, or *"h24"*.
  • [[LocaleData]].[[<_locale_>]].[[hourCycle12]] must be one of the String values *"h11"* or *"h12"*.
  • [[LocaleData]].[[<_locale_>]].[[hourCycle24]] must be one of the String values *"h23"* or *"h24"*.
  • [[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this [[formats]] field must be a Record with a [[<_calendar_>]] field for each calendar value _calendar_. The value of each [[<_calendar_>]] field must be a List of DateTime Format Records. Multiple Records in such a List may use the same subset of the fields as long as the corresponding values differ for at least one field. The following subsets must be available for each locale:
    • weekday, year, month, day, hour, minute, second, fractionalSecondDigits
    • weekday, year, month, day, hour, minute, second
    • weekday, year, month, day
    • year, month, day
    • year, month
    • month, day
    • month
    • hour, minute, second, fractionalSecondDigits
    • hour, minute, second
    • hour, minute
    • dayPeriod, hour
    • dayPeriod, hour, minute, second
    • dayPeriod, hour, minute
  • [[LocaleData]].[[<_locale_>]] must have a [[styles]] field. The value of this [[styles]] field must be a Record with a [[<_calendar_>]] field for each calendar value _calendar_. The value of each [[<_calendar_>]] field must be a DateTime Styles Record.

Abstract Operations for DateTimeFormat Objects

GetDateTimeFormat ( _formats_: a List of DateTime Format Records, _matcher_: *"basic"* or *"best fit"*, _options_: a Record, _required_: ~date~, ~time~, ~year-month~, ~month-day~, or ~any~, _defaults_: ~date~, ~time~, ~year-month~, ~month-day~, ~zoned-date-time~, or ~all~, _inherit_: ~all~ or ~relevant~, ): a DateTime Format Record or *null*

1. If _required_ is ~date~, then 1. Let _requiredOptions_ be « *"weekday"*, *"year"*, *"month"*, *"day"* ». 1. Else if _required_ is ~time~, then 1. Let _requiredOptions_ be « *"dayPeriod"*, *"hour"*, *"minute"*, *"second"*, *"fractionalSecondDigits"* ». 1. Else if _required_ is ~year-month~, then 1. Let _requiredOptions_ be « *"year"*, *"month"* ». 1. Else if _required_ is ~month-day~, then 1. Let _requiredOptions_ be « *"month"*, *"day"* ». 1. Else, 1. Assert: _required_ is ~any~. 1. Let _requiredOptions_ be « *"weekday"*, *"year"*, *"month"*, *"day"*, *"dayPeriod"*, *"hour"*, *"minute"*, *"second"*, *"fractionalSecondDigits"* ». 1. If _defaults_ is ~date~, then 1. Let _defaultOptions_ be « *"year"*, *"month"*, *"day"* ». 1. Else if _defaults_ is ~time~, then 1. Let _defaultOptions_ be « *"hour"*, *"minute"*, *"second"* ». 1. Else if _defaults_ is ~year-month~, then 1. Let _defaultOptions_ be « *"year"*, *"month"* ». 1. Else if _defaults_ is ~month-day~, then 1. Let _defaultOptions_ be « *"month"*, *"day"* ». 1. Else, 1. Assert: _defaults_ is ~zoned-date-time~ or ~all~. 1. Let _defaultOptions_ be « *"year"*, *"month"*, *"day"*, *"hour"*, *"minute"*, *"second"* ». 1. If _inherit_ is ~all~, then 1. Let _formatOptions_ be a copy of _options_. 1. Else, 1. Let _formatOptions_ be a new Record. 1. If _required_ is one of ~date~, ~year-month~, or ~any~, then 1. Set _formatOptions_.[[era]] to _options_.[[era]]. 1. If _required_ is ~time~ or ~any~, then 1. Set _formatOptions_.[[hourCycle]] to _options_.[[hourCycle]]. 1. Let _anyPresent_ be *false*. 1. For each property name _prop_ of « *"weekday"*, *"year"*, *"month"*, *"day"*, *"era"*, *"dayPeriod"*, *"hour"*, *"minute"*, *"second"*, *"fractionalSecondDigits"* », do 1. If _options_.[[<_prop_>]] is not *undefined*, set _anyPresent_ to *true*. 1. Let _needDefaults_ be *true*. 1. For each property name _prop_ of _requiredOptions_, do 1. Let _value_ be _options_.[[<_prop_>]]. 1. If _value_ is not *undefined*, then 1. Set _formatOptions_.[[<_prop_>]] to _value_. 1. Set _needDefaults_ to *false*. 1. If _needDefaults_ is *true*, then 1. If _anyPresent_ is *true* and _inherit_ is ~relevant~, return *null*. 1. For each property name _prop_ of _defaultOptions_, do 1. Set _formatOptions_.[[<_prop_>]] to *"numeric"*. 1. If _defaults_ is ~zoned-date-time~ and _formatOptions_.[[timeZoneName]] is *undefined*, then 1. Set _formatOptions_.[[timeZoneName]] to *"short"*. 1. If _matcher_ is *"basic"*, then 1. Let _bestFormat_ be BasicFormatMatcher(_formatOptions_, _formats_). 1. Else, 1. Let _bestFormat_ be BestFitFormatMatcher(_formatOptions_, _formats_). 1. Return _bestFormat_.

AdjustDateTimeStyleFormat ( _formats_: a List of DateTime Format Records, _baseFormat_: a DateTime Format Record, _matcher_: *"basic"* or *"best fit"*, _allowedOptions_: a List of field names, ): a DateTime Format Record

description
It inspects _baseFormat_ and determines the closest format to it that only includes fields from _allowedOptions_. This is used for determining the best format for Temporal objects with the `"dateStyle"` or `"timeStyle"` options. For example, a locale's best format for `"dateStyle": "full"` might include the weekday, which is not applicable when formatting a `Temporal.PlainYearMonth` object.
1. Let _formatOptions_ be a new Record. 1. For each field name _fieldName_ of _allowedOptions_, do 1. Set the field of _formatOptions_ whose name is _fieldName_ to the value of the field of _baseFormat_ whose name is _fieldName_. 1. If _matcher_ is *"basic"*, then 1. Let _bestFormat_ be BasicFormatMatcher(_formatOptions_, _formats_). 1. Else, 1. Let _bestFormat_ be BestFitFormatMatcher(_formatOptions_, _formats_). 1. Return _bestFormat_.

DateTime Format Functions

A DateTime format function is an anonymous built-in function that has a [[DateTimeFormat]] internal slot.

When a DateTime format function _F_ is called with optional argument _date_, the following steps are taken:

1. Let _dtf_ be _F_.[[DateTimeFormat]]. 1. Assert: _dtf_ is an Object and _dtf_ has an [[InitializedDateTimeFormat]] internal slot. 1. If _date_ is not provided or is *undefined*, then 1. Let _x_ be ! Call(%Date.now%, *undefined*). 1. Else, 1. Let _x_ be ? ToNumberToDateTimeFormattable(_date_). 1. Return ? FormatDateTime(_dtf_, _x_).

The *"length"* property of a DateTime format function is *1*𝔽.

PartitionDateTimePattern ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing a List of Records with fields [[Type]] (a String) and [[Value]] (a String), or a throw completion

description
It interprets _x_ as a time value as specified in es2024, an epoch time, and creates the corresponding parts according to the type of _x_, effective locale, and the formatting options of _dateTimeFormat_.
1. Let _x_ be TimeClip(_x_). 1. If _x_ is *NaN*, throw a *RangeError* exception. 1. Let _epochNanoseconds_ be ℤ(ℝ(_x_) × 106). 1. Let _format_ be _dateTimeFormat_.[[DateTimeFormat]]. 1. Let _formatRecord_ be ? HandleDateTimeValue(_dateTimeFormat_, _x_). 1. Let _epochNanoseconds_ be _formatRecord_.[[EpochNanoseconds]]. 1. Let _format_ be _formatRecord_.[[Format]]. 1. If _format_ has a field [[hour]] and _dateTimeFormat_.[[HourCycle]] is *"h11"* or *"h12"*, then 1. Let _pattern_ be _format_.[[pattern12]]. 1. Else, 1. Let _pattern_ be _format_.[[pattern]]. 1. Let _result_ be FormatDateTimePattern(_dateTimeFormat_, _format_, _pattern_, _epochNanoseconds_). 1. Return _result_.

FormatDateTime ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing a String or a throw completion

1. Let _parts_ be ? PartitionDateTimePattern(_dateTimeFormat_, _x_). 1. Let _result_ be the empty String. 1. For each Record { [[Type]], [[Value]] } _part_ of _parts_, do 1. Set _result_ to the string-concatenation of _result_ and _part_.[[Value]]. 1. Return _result_.

FormatDateTimeToParts ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing an Array or a throw completion

1. Let _parts_ be ? PartitionDateTimePattern(_dateTimeFormat_, _x_). 1. Let _result_ be ! ArrayCreate(0). 1. Let _n_ be 0. 1. For each Record { [[Type]], [[Value]] } _part_ of _parts_, do 1. Let _O_ be OrdinaryObjectCreate(%Object.prototype%). 1. Perform ! CreateDataPropertyOrThrow(_O_, *"type"*, _part_.[[Type]]). 1. Perform ! CreateDataPropertyOrThrow(_O_, *"value"*, _part_.[[Value]]). 1. Perform ! CreateDataPropertyOrThrow(_result_, ! ToString(𝔽(_n_)), _O_). 1. Increment _n_ by 1. 1. Return _result_.

PartitionDateTimeRangePattern ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number or an Object for which IsTemporalObject returns *true*, _y_: a Number or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing a List of Records with fields [[Type]] (a String), [[Value]] (a String), and [[Source]] (a String), or a throw completion

description
It interprets _x_ and _y_ a time value as specified in es2024, epoch times, and creates the corresponding parts according to the types of _x_ and _y_, effective locale, and the formatting options of _dateTimeFormat_.
1. Let _x_ be TimeClip(_x_). 1. If _x_ is *NaN*, throw a *RangeError* exception. 1. Let _y_ be TimeClip(_y_). 1. If _y_ is *NaN*, throw a *RangeError* exception. 1. Let _xEpochNanoseconds_ be ℤ(ℝ(_x_) × 106). 1. Let _yEpochNanoseconds_ be ℤ(ℝ(_y_) × 106). 1. If IsTemporalObject(_x_) is *true* or IsTemporalObject(_y_) is *true*, then 1. If SameTemporalType(_x_, _y_) is *false*, throw a *TypeError* exception. 1. Let _xFormatRecord_ be ? HandleDateTimeValue(_dateTimeFormat_, _x_). 1. Let _yFormatRecord_ be ? HandleDateTimeValue(_dateTimeFormat_, _y_). 1. Let _xEpochNanoseconds_ be _xFormatRecord_.[[EpochNanoseconds]]. 1. Let _yEpochNanoseconds_ be _yFormatRecord_.[[EpochNanoseconds]]. 1. Let _tm1_ be ToLocalTime(_xEpochNanoseconds_, _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). 1. Let _tm2_ be ToLocalTime(_yEpochNanoseconds_, _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). 1. Let _format_ be _dateTimeFormat_.[[DateTimeFormat]]. 1. Let _format_ be _xFormatRecord_.[[Format]]. 1. Assert: _format_ is equal to _yFormatRecord_.[[Format]]. 1. If _format_ has a field [[hour]] and _dateTimeFormat_.[[HourCycle]] is *"h11"* or *"h12"*, then 1. Let _pattern_ be _format_.[[pattern12]]. 1. Let _rangePatterns_ be _format_.[[rangePatterns12]]. 1. Else, 1. Let _pattern_ be _format_.[[pattern]]. 1. Let _rangePatterns_ be _format_.[[rangePatterns]]. 1. Let _selectedRangePattern_ be *undefined*. 1. Let _relevantFieldsEqual_ be *true*. 1. Let _checkMoreFields_ be *true*. 1. For each row of , except the header row, in table order, do 1. Let _fieldName_ be the name given in the Field Name column of the row. 1. If _rangePatterns_ has a field whose name is _fieldName_, let _rangePattern_ be _rangePatterns_' field whose name is _fieldName_; else let _rangePattern_ be *undefined*. 1. If _selectedRangePattern_ is not *undefined* and _rangePattern_ is *undefined*, then 1. NOTE: Because there is no range pattern for differences at or below this field, no further checks will be performed. 1. Set _checkMoreFields_ to *false*. 1. If _fieldName_ is not equal to [[Default]] and _relevantFieldsEqual_ is *true* and _checkMoreFields_ is *true*, then 1. Set _selectedRangePattern_ to _rangePattern_. 1. If _fieldName_ is [[AmPm]], then 1. If _tm1_.[[Hour]] is less than 12, let _v1_ be *"am"*; else let _v1_ be *"pm"*. 1. If _tm2_.[[Hour]] is less than 12, let _v2_ be *"am"*; else let _v2_ be *"pm"*. 1. Else if _fieldName_ is [[DayPeriod]], then 1. Let _v1_ be a String value representing the day period of _tm1_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. 1. Let _v2_ be a String value representing the day period of _tm2_; the String value depends upon the implementation and the effective locale of _dateTimeFormat_. 1. Else if _fieldName_ is [[FractionalSecondDigits]], then 1. Let _fractionalSecondDigits_ be _dateTimeFormat_.[[FractionalSecondDigits]]. 1. If _fractionalSecondDigits_ is *undefined*, then 1. Set _fractionalSecondDigits_ to 3. 1. Let _exp_ be _fractionalSecondDigits_ - 3. 1. Let _v1_ be floor(_tm1_.[[Millisecond]] × 10_exp_). 1. Let _v2_ be floor(_tm2_.[[Millisecond]] × 10_exp_). 1. Else, 1. Let _v1_ be _tm1_'s field whose name is _fieldName_. 1. Let _v2_ be _tm2_'s field whose name is _fieldName_. 1. If _v1_ is not equal to _v2_, then 1. Set _relevantFieldsEqual_ to *false*. 1. If _relevantFieldsEqual_ is *true*, then 1. Let _collapsedResult_ be a new empty List. 1. Let _resultParts_ be FormatDateTimePattern(_dateTimeFormat_, _format_, _pattern_, _xEpochNanoseconds_). 1. For each Record { [[Type]], [[Value]] } _r_ of _resultParts_, do 1. Append the Record { [[Type]]: _r_.[[Type]], [[Value]]: _r_.[[Value]], [[Source]]: *"shared"* } to _collapsedResult_. 1. Return _collapsedResult_. 1. Let _rangeResult_ be a new empty List. 1. If _selectedRangePattern_ is *undefined*, then 1. Set _selectedRangePattern_ to _rangePatterns_.[[Default]]. 1. For each Record { [[Pattern]], [[Source]] } _rangePatternPart_ of _selectedRangePattern_.[[PatternParts]], do 1. Let _pattern_ be _rangePatternPart_.[[Pattern]]. 1. Let _source_ be _rangePatternPart_.[[Source]]. 1. If _source_ is *"startRange"* or *"shared"*, then 1. Let _z_ be _xEpochNanoseconds_. 1. Else, 1. Let _z_ be _yEpochNanoseconds_. 1. Let _resultParts_ be FormatDateTimePattern(_dateTimeFormat_, _selectedRangePattern_, _pattern_, _z_). 1. For each Record { [[Type]], [[Value]] } _r_ of _resultParts_, do 1. Append the Record { [[Type]]: _r_.[[Type]], [[Value]]: _r_.[[Value]], [[Source]]: _source_ } to _rangeResult_. 1. Return _rangeResult_.

FormatDateTimeRange ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number or an Object for which IsTemporalObject returns *true*, _y_: a Number or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing a String or a throw completion

1. Let _parts_ be ? PartitionDateTimeRangePattern(_dateTimeFormat_, _x_, _y_). 1. Let _result_ be the empty String. 1. For each Record { [[Type]], [[Value]], [[Source]] } _part_ of _parts_, do 1. Set _result_ to the string-concatenation of _result_ and _part_.[[Value]]. 1. Return _result_.

FormatDateTimeRangeToParts ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number or an Object for which IsTemporalObject returns *true*, _y_: a Number or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing an Array or a throw completion

1. Let _parts_ be ? PartitionDateTimeRangePattern(_dateTimeFormat_, _x_, _y_). 1. Let _result_ be ! ArrayCreate(0). 1. Let _n_ be 0. 1. For each Record { [[Type]], [[Value]], [[Source]] } _part_ of _parts_, do 1. Let _O_ be OrdinaryObjectCreate(%Object.prototype%). 1. Perform ! CreateDataPropertyOrThrow(_O_, *"type"*, _part_.[[Type]]). 1. Perform ! CreateDataPropertyOrThrow(_O_, *"value"*, _part_.[[Value]]). 1. Perform ! CreateDataPropertyOrThrow(_O_, *"source"*, _part_.[[Source]]). 1. Perform ! CreateDataPropertyOrThrow(_result_, ! ToString(𝔽(_n_)), _O_). 1. Increment _n_ by 1. 1. Return _result_.

ToDateTimeFormattable ( _value_: an ECMAScript language value, but not *undefined*, ): either a normal completion containing either a Number or an Object for which IsTemporalObject returns *true*, or a throw completion

description
It converts _value_ to a value that can be formatted by an %Intl.DateTimeFormat% object.
1. If IsTemporalObject(_value_) is *true*, return _value_. 1. Return ? ToNumber(_value_).

IsTemporalObject ( _value_: an ECMAScript language value, ): a Boolean

1. If _value_ is not an Object, then 1. Return *false*. 1. If _value_ does not have an [[InitializedTemporalDate]], [[InitializedTemporalTime]], [[InitializedTemporalDateTime]], [[InitializedTemporalZonedDateTime]], [[InitializedTemporalYearMonth]], [[InitializedTemporalMonthDay]], or [[InitializedTemporalInstant]] internal slot, then 1. Return *false*. 1. Return *true*.

SameTemporalType ( _x_: an ECMAScript language value, _y_: an ECMAScript language value, ): a Boolean

description
It determines whether _x_ and _y_ are both instances of the same Temporal type.
1. If either of IsTemporalObject(_x_) or IsTemporalObject(_y_) is *false*, return *false*. 1. If _x_ has an [[InitializedTemporalDate]] internal slot and _y_ does not, return *false*. 1. If _x_ has an [[InitializedTemporalTime]] internal slot and _y_ does not, return *false*. 1. If _x_ has an [[InitializedTemporalDateTime]] internal slot and _y_ does not, return *false*. 1. If _x_ has an [[InitializedTemporalZonedDateTime]] internal slot and _y_ does not, return *false*. 1. If _x_ has an [[InitializedTemporalYearMonth]] internal slot and _y_ does not, return *false*. 1. If _x_ has an [[InitializedTemporalMonthDay]] internal slot and _y_ does not, return *false*. 1. If _x_ has an [[InitializedTemporalInstant]] internal slot and _y_ does not, return *false*. 1. Return *true*.

Value Format Records

Each Value Format Record has the fields defined in .

Record returned by HandleDateTimeValue
Field Name Value Type
[[Format]] a DateTime Format Record
[[EpochNanoseconds]] a BigInt

HandleDateTimeTemporalDate ( _dateTimeFormat_: an Intl.DateTimeFormat, _temporalDate_: a Temporal.PlainDate, ): either a normal completion containing a Value Format Record or a throw completion

1. If _temporalDate_.[[Calendar]] is not _dateTimeFormat_.[[Calendar]] or *"iso8601"*, throw a *RangeError* exception. 1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_temporalDate_.[[ISODate]], NoonTimeRecord()). 1. Let _epochNs_ be ? GetEpochNanosecondsFor(_dateTimeFormat_.[[TimeZone]], _isoDateTime_, ~compatible~). 1. Let _format_ be _dateTimeFormat_.[[TemporalPlainDateFormat]]. 1. If _format_ is *null*, throw a *TypeError* exception. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _epochNs_ }.

HandleDateTimeTemporalYearMonth ( _dateTimeFormat_: an Intl.DateTimeFormat, _temporalYearMonth_: a Temporal.PlainYearMonth, ): either a normal completion containing a Value Format Record or a throw completion

1. If _temporalYearMonth_.[[Calendar]] is not equal to _dateTimeFormat_.[[Calendar]], then 1. Throw a *RangeError* exception. 1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_temporalYearMonth_.[[ISODate]], NoonTimeRecord()). 1. Let _epochNs_ be ? GetEpochNanosecondsFor(_dateTimeFormat_.[[TimeZone]], _isoDateTime_, ~compatible~). 1. Let _format_ be _dateTimeFormat_.[[TemporalPlainYearMonthFormat]]. 1. If _format_ is *null*, throw a *TypeError* exception. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _epochNs_ }.

HandleDateTimeTemporalMonthDay ( _dateTimeFormat_: an Intl.DateTimeFormat, _temporalMonthDay_: a Temporal.PlainMonthDay, ): either a normal completion containing a Value Format Record or a throw completion

1. If _temporalMonthDay_.[[Calendar]] is not equal to _dateTimeFormat_.[[Calendar]], then 1. Throw a *RangeError* exception. 1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_temporalMonthDay_.[[ISODate]], NoonTimeRecord()). 1. Let _epochNs_ be ? GetEpochNanosecondsFor(_dateTimeFormat_.[[TimeZone]], _isoDateTime_, ~compatible~). 1. Let _format_ be _dateTimeFormat_.[[TemporalPlainMonthDayFormat]]. 1. If _format_ is *null*, throw a *TypeError* exception. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _epochNs_ }.

HandleDateTimeTemporalTime ( _dateTimeFormat_: an Intl.DateTimeFormat, _temporalTime_: a Temporal.PlainTime, ): either a normal completion containing a Value Format Record or a throw completion

1. Let _isoDate_ be CreateISODateRecord(1970, 1, 1). 1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_isoDate_, _temporalTime_.[[Time]]). 1. Let _epochNs_ be ? GetEpochNanosecondsFor(_dateTimeFormat_.[[TimeZone]], _isoDateTime_, ~compatible~). 1. Let _format_ be _dateTimeFormat_.[[TemporalPlainTimeFormat]]. 1. If _format_ is *null*, throw a *TypeError* exception. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _epochNs_ }.

HandleDateTimeTemporalDateTime ( _dateTimeFormat_: an Intl.DateTimeFormat, _dateTime_: a Temporal.PlainDateTime, ): either a normal completion containing a Value Format Record or a throw completion

1. If _dateTime_.[[Calendar]] is not *"iso8601"* and not equal to _dateTimeFormat_.[[Calendar]], then 1. Throw a *RangeError* exception. 1. Let _epochNs_ be ? GetEpochNanosecondsFor(_dateTimeFormat_.[[TimeZone]], _dateTime_.[[ISODateTime]], ~compatible~). 1. Let _format_ be _dateTimeFormat_.[[TemporalPlainDateTimeFormat]]. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _epochNs_ }.

HandleDateTimeTemporalInstant ( _dateTimeFormat_: an Intl.DateTimeFormat, _instant_: a Temporal.Instant, ): a Value Format Record

1. Let _format_ be _dateTimeFormat_.[[TemporalInstantFormat]]. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _instant_.[[EpochNanoseconds]] }.

HandleDateTimeOthers ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number, ): either a normal completion containing a Value Format Record or a throw completion

1. Set _x_ to TimeClip(_x_). 1. If _x_ is *NaN*, throw a *RangeError* exception. 1. Let _epochNanoseconds_ be ℤ(ℝ(_x_) × 106). 1. Let _format_ be _dateTimeFormat_.[[DateTimeFormat]]. 1. Return Value Format Record { [[Format]]: _format_, [[EpochNanoseconds]]: _epochNanoseconds_ }.

HandleDateTimeValue ( _dateTimeFormat_: an Intl.DateTimeFormat, _x_: a Number, or an Object for which IsTemporalObject returns *true*, ): either a normal completion containing a Value Format Record or a throw completion

1. If _x_ is an Object, then 1. If _x_ has an [[InitializedTemporalDate]] internal slot, then 1. Return ? HandleDateTimeTemporalDate(_dateTimeFormat_, _x_). 1. If _x_ has an [[InitializedTemporalYearMonth]] internal slot, then 1. Return ? HandleDateTimeTemporalYearMonth(_dateTimeFormat_, _x_). 1. If _x_ has an [[InitializedTemporalMonthDay]] internal slot, then 1. Return ? HandleDateTimeTemporalMonthDay(_dateTimeFormat_, _x_). 1. If _x_ has an [[InitializedTemporalTime]] internal slot, then 1. Return ? HandleDateTimeTemporalTime(_dateTimeFormat_, _x_). 1. If _x_ has an [[InitializedTemporalDateTime]] internal slot, then 1. Return ? HandleDateTimeTemporalDateTime(_dateTimeFormat_, _x_). 1. If _x_ has an [[InitializedTemporalInstant]] internal slot, then 1. Return HandleDateTimeTemporalInstant(_dateTimeFormat_, _x_). 1. Assert: _x_ has an [[InitializedTemporalZonedDateTime]] internal slot. 1. Throw a *TypeError* exception. 1. Return ? HandleDateTimeOthers(_dateTimeFormat_, _x_).

ToLocalTime ( _epochNs_: a BigInt, _calendar_: a String, _timeZoneIdentifier_: a String, ): a ToLocalTime Record

description
1. If IsTimeZoneOffsetString(_timeZoneIdentifier_) is *true*, then 1. Let _offsetNs_ be ParseTimeZoneOffsetString! ParseDateTimeUTCOffset(_timeZoneIdentifier_). 1. Else, 1. Assert: GetAvailableNamedTimeZoneIdentifier(_timeZoneIdentifier_) is not ~empty~. 1. Let _offsetNs_ be GetNamedTimeZoneOffsetNanoseconds(_timeZoneIdentifier_, _epochNs_). 1. Let _tz_ be ℝ(_epochNs_) + _offsetNs_. 1. If _calendar_ is *"gregory"*, then 1. Return a ToLocalTime Record with fields calculated from _tz_ according to . 1. Else, 1. Return a ToLocalTime Record with the fields calculated from _tz_ for the given _calendar_. The calculations should use best available information about the specified _calendar_. Given the same values of _epochNs_, _calendar_, and _timeZoneIdentifier_, the result must be the same for the lifetime of the surrounding agent. A conforming implementation must recognize *"UTC"* and all Zone and Link names from the IANA Time Zone Database (and only such names), and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. Time zone information is subject to change, and host environments may update their time zone database at any time. At a minimum, implementations must ensure that the time zone information for each particular value of _timeZone_ individually remains constant starting from the time it is first accessed, for the lifetime of the surrounding agent. Furthermore, it is recommended that the time zone information for all values of _timeZone_ as a whole (i.e. the time zone database) remains the same for the lifetime of the surrounding agent.

Properties of the Intl.DateTimeFormat Prototype Object

Intl.DateTimeFormat.prototype.formatToParts ( _date_ )

When the `formatToParts` method is called with an argument _date_, the following steps are taken:

1. Let _dtf_ be the *this* value. 1. Perform ? RequireInternalSlot(_dtf_, [[InitializedDateTimeFormat]]). 1. If _date_ is *undefined*, then 1. Let _x_ be ! Call(%Date.now%, *undefined*). 1. Else, 1. Let _x_ be ? ToNumberToDateTimeFormattable(_date_). 1. Return ? FormatDateTimeToParts(_dtf_, _x_).

Intl.DateTimeFormat.prototype.formatRange ( _startDate_, _endDate_ )

When the `formatRange` method is called with an arguments _startDate_ and _endDate_, the following steps are taken:

1. Let _dtf_ be *this* value. 1. Perform ? RequireInternalSlot(_dtf_, [[InitializedDateTimeFormat]]). 1. If _startDate_ is *undefined* or _endDate_ is *undefined*, throw a *TypeError* exception. 1. Let _x_ be ? ToNumberToDateTimeFormattable(_startDate_). 1. Let _y_ be ? ToNumberToDateTimeFormattable(_endDate_). 1. Return ? FormatDateTimeRange(_dtf_, _x_, _y_).

Intl.DateTimeFormat.prototype.formatRangeToParts ( _startDate_, _endDate_ )

When the `formatRangeToParts` method is called with arguments _startDate_ and _endDate_, the following steps are taken:

1. Let _dtf_ be *this* value. 1. Perform ? RequireInternalSlot(_dtf_, [[InitializedDateTimeFormat]]). 1. If _startDate_ is *undefined* or _endDate_ is *undefined*, throw a *TypeError* exception. 1. Let _x_ be ? ToNumberToDateTimeFormattable(_startDate_). 1. Let _y_ be ? ToNumberToDateTimeFormattable(_endDate_). 1. Return ? FormatDateTimeRangeToParts(_dtf_, _x_, _y_).

Properties of Intl.DateTimeFormat Instances

Intl.DateTimeFormat instances are ordinary objects that inherit properties from %Intl.DateTimeFormat.prototype%.

Intl.DateTimeFormat instances have an [[InitializedDateTimeFormat]] internal slot.

Intl.DateTimeFormat instances also have several internal slots that are computed by the constructor:

Finally, Intl.DateTimeFormat instances have a [[BoundFormat]] internal slot that caches the function returned by the format accessor ().

Locale Sensitive Functions of the ECMAScript Language Specification

Properties of the Temporal.Duration Prototype Object

Temporal.Duration.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This function is currently not specified. See the Intl.DurationFormat proposal.

Properties of the Temporal.Instant Prototype Object

Temporal.Instant.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _instant_ be the *this* value. 1. Perform ? RequireInternalSlot(_instant_, [[InitializedTemporalInstant]]). 1. Let _dateFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~any~, ~all~). 1. Return ? FormatDateTime(_dateFormat_, _instant_).

Properties of the Temporal.PlainDate Prototype Object

Temporal.PlainDate.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _temporalDate_ be the *this* value. 1. Perform ? RequireInternalSlot(_temporalDate_, [[InitializedTemporalDate]]). 1. Let _dateFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~date~, ~date~). 1. Return ? FormatDateTime(_dateFormat_, _temporalDate_).

Properties of the Temporal.PlainDateTime Prototype Object

Temporal.PlainDateTime.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _dateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_dateTime_, [[InitializedTemporalDateTime]]). 1. Let _dateFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~any~, ~all~). 1. Return ? FormatDateTime(_dateFormat_, _dateTime_).

Properties of the Temporal.PlainMonthDay Prototype Object

Temporal.PlainMonthDay.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _monthDay_ be the *this* value. 1. Perform ? RequireInternalSlot(_monthDay_, [[InitializedTemporalMonthDay]]). 1. Let _dateFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~date~, ~date~). 1. Return ? FormatDateTime(_dateFormat_, _monthDay_).

Properties of the Temporal.PlainTime Prototype Object

Temporal.PlainTime.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _temporalTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_temporalTime_, [[InitializedTemporalTime]]). 1. Let _dateFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~time~, ~time~). 1. Return ? FormatDateTime(_dateFormat_, _temporalTime_).

Properties of the Temporal.PlainYearMonth Prototype Object

Temporal.PlainYearMonth.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _yearMonth_ be the *this* value. 1. Perform ? RequireInternalSlot(_yearMonth_, [[InitializedTemporalYearMonth]]). 1. Let _dateFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~date~, ~date~). 1. Return ? FormatDateTime(_dateFormat_, _yearMonth_).

Properties of the Temporal.ZonedDateTime Prototype Object

Temporal.ZonedDateTime.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

This definition supersedes the definition provided in .

This method performs the following steps when called:

1. Let _zonedDateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_zonedDateTime_, [[InitializedTemporalZonedDateTime]]). 1. Let _dateTimeFormat_ be ? CreateDateTimeFormat(%Intl.DateTimeFormat%, _locales_, _options_, ~any~, ~all~, _zonedDateTime_.[[TimeZone]]). 1. If _zonedDateTime_.[[Calendar]] is not *"iso8601"* and CalendarEquals(_zonedDateTime_.[[Calendar]], _dateTimeFormat_.[[Calendar]]) is *false*, then 1. Throw a *RangeError* exception. 1. Let _instant_ be ! CreateTemporalInstant(_zonedDateTime_.[[EpochNanoseconds]]). 1. Return ? FormatDateTime(_dateTimeFormat_, _instant_).