From aea146dbd1f015bd7a0d03dc23accbef26529e59 Mon Sep 17 00:00:00 2001 From: Ujjwal Sharma Date: Wed, 3 Feb 2021 20:24:28 +0530 Subject: [PATCH] WIP rebase ecma402 --- spec/biblio.json | 15 +++++ spec/intl.html | 167 ++++++++++++++++++++++++----------------------- 2 files changed, 99 insertions(+), 83 deletions(-) diff --git a/spec/biblio.json b/spec/biblio.json index df0e0fb7e9..0c5bef9af5 100644 --- a/spec/biblio.json +++ b/spec/biblio.json @@ -101,6 +101,21 @@ "type": "term", "term": "%NumberFormat%", "id": "sec-intl-numberformat-constructor" + }, + { + "type": "clause", + "number": "Table 7", + "id": "table-datetimeformat-components" + }, + { + "type": "clause", + "number": "Table 8", + "id": "table-datetimeformat-tolocaltime-record" + }, + { + "type": "op", + "aoid": "DateTimeStyleFormat", + "id": "sec-date-time-style-format" } ], "https://tc39.es/proposal-intl-duration-format/": [ diff --git a/spec/intl.html b/spec/intl.html index 7b77b2d489..78a4730c3b 100644 --- a/spec/intl.html +++ b/spec/intl.html @@ -9,6 +9,9 @@

Amendments to the ECMAScript® 2021 Internationalization API SpecificationECMA-402, the ECMAScript® 2021 Internationalization API Specification. Text to be added is marked like this, and text to be deleted is marked like this.

+

+ This text is based on top of the ECMA-402 spec text from commit b5edf2cdcca8d69590796cd41abf8399d249b8a1. +

@@ -83,64 +86,6 @@

DefaultTimeZone (

Abstract Operations For DateTimeFormat Objects

- - Components of date and time formats - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Internal SlotPropertyValues
[[Weekday]]*"weekday"**"narrow"*, *"short"*, *"long"*
[[Era]]*"era"**"narrow"*, *"short"*, *"long"*
[[Year]]*"year"**"2-digit"*, *"numeric"*
[[Month]]*"month"**"2-digit"*, *"numeric"*, *"narrow"*, *"short"*, *"long"*
[[Day]]*"day"**"2-digit"*, *"numeric"*
[[Hour]]*"hour"**"2-digit"*, *"numeric"*
[[Minute]]*"minute"**"2-digit"*, *"numeric"*
[[Second]]*"second"**"2-digit"*, *"numeric"*
[[TimeZoneName]]*"timeZoneName"**"short"*, *"long"*
-
-

InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )

@@ -167,12 +112,12 @@

InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )

1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a *RangeError* exception. 1. Set _opt_.[[nu]] to _numberingSystem_. 1. Let _hour12_ be ? GetOption(_options_, *"hour12"*, *"boolean"*, *undefined*, *undefined*). - 1. Let _hourCycle_ be ? GetOption(_options_, *"hourCycle"*, *"string"*, « *"h11"*, *"h12"*, *"h23"*, *"h24"* », *undefined*). + 1. Let _hourCycle_ be ? GetOption(_options_, *"hourCycle"*, *"string"*, « *"h11"*, *"h12"*, *"h23"*, *"h24"* », *undefined*). 1. If _hour12_ is not *undefined*, then 1. Let _hourCycle_ be *null*. 1. Set _opt_.[[hc]] to _hourCycle_. 1. Let _localeData_ be %DateTimeFormat%.[[LocaleData]]. - 1. Let _r_ be ResolveLocale( %DateTimeFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DateTimeFormat%.[[RelevantExtensionKeys]], _localeData_). + 1. Let _r_ be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DateTimeFormat%.[[RelevantExtensionKeys]], _localeData_). 1. Set _dateTimeFormat_.[[Locale]] to _r_.[[locale]]. 1. Let _calendar_ be _r_.[[ca]]. 1. Set _dateTimeFormat_.[[Calendar]] to _calendar_. @@ -209,15 +154,40 @@

InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )

1. Let _opt_ be a new Record. 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. Let _value_ be ? GetOption(_options_, _prop_, *"string"*, « the strings given in the Values column of the row », *undefined*). + 1. If _prop_ is *"fractionalSecondDigits"*, then + 1. Let _value_ be ? GetNumberOption(options, *"fractionalSecondDigits"*, 1, 3, *undefined*). + 1. Else, + 1. Let _value_ be ? GetOption(_options_, _prop_, *"string"*, « the strings given in the Values column of the row », *undefined*). 1. Set _opt_.[[<_prop_>]] to _value_. 1. Let _dataLocaleData_ be _localeData_.[[<_dataLocale_>]]. - 1. Let _formats_ be _dataLocaleData_.[[formats]].[[<_calendar_>]]. 1. Let _matcher_ be ? GetOption(_options_, *"formatMatcher"*, *"string"*, « *"basic"*, *"best fit"* », *"best fit"*). - 1. If _matcher_ is *"basic"*, then - 1. Let _bestFormat_ be BasicFormatMatcher(_opt_, _formats_). - 1. Else, - 1. Let _bestFormat_ be BestFitFormatMatcher(_opt_, _formats_). + 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. If _dateStyle_ is not *undefined* or _timeStyle_ is not *undefined*, then + 1. For each row in , except the header row, do + 1. Let _prop_ be the name given in the Property column of the row. + 1. Let _p_ be _opt_.[[<_prop_>]]. + 1. If _p_ is not *undefined*, then + 1. Throw a *TypeError* exception. + 1. Let _bestFormat_ be DateTimeStyleFormat(_dateStyle_, _timeStyle_, _dataLocaleData_). + 1. TODO: figure out how to deal with Temporal objects here. + 1. Else, + 1. Let _formats_ be _dataLocaleData_.[[formats]].[[<_calendar_>]]. + 1. If _matcher_ is *"basic"*, then + 1. Let _bestFormat_ be BasicFormatMatcher(_opt_, _formats_). + 1. Else, + 1. Let _bestFormat_ be BestFitFormatMatcher(_opt_, _formats_). + 1. Let _expandedOptions_ be a copy of _opt_. + 1. Let _needDefaults_ be *true*. + 1. For each element _field_ of « *"weekday"*, *"year"*, *"month"*, *"day"*, *"hour"*, *"minute"*, *"second"* » in List order, do + 1. If _expandedOptions_.[[<_field_>]] is not *undefined*, then + 1. Set _needDefaults_ to *false*. + 1. If _needDefaults_ is *true*, then + 1. For each element _field_ of « *"year"*, *"month"*, *"day"*, *"hour"*, *"minute"*, *"second"* » in List order, do + 1. Set _expandedOptions_.[[<_field_>]] to *"numeric"*. + 1. Let _bestFormat_ be GetDateTimeFormatPattern(_matcher_, _expandedOptions_, _formats_, _hc_). 1. For each row in , except the header row, in table order, do 1. Let _prop_ be the name given in the Property column of the row. 1. Let _p_ be _bestFormat_.[[<_prop_>]]. @@ -248,18 +218,7 @@

InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )

1. Let _pattern_ be _bestFormat_.[[pattern12]]. 1. Else, 1. Let _pattern_ be _bestFormat_.[[pattern]]. - 1. Else, - 1. Set _dateTimeFormat_.[[HourCycle]] to *undefined*. - 1. Let _pattern_ be _bestFormat_.[[pattern]]. - 1. Let _expandedOptions_ be a copy of _opt_. - 1. Let _needDefaults_ be *true*. - 1. For each element _field_ of « *"weekday"*, *"year"*, *"month"*, *"day"*, *"hour"*, *"minute"*, *"second"* » in List order, do - 1. If _expandedOptions_.[[<_field_>]] is not *undefined*, then - 1. Set _needDefaults_ to *false*. - 1. If _needDefaults_ is *true*, then - 1. For each element _field_ of « *"year"*, *"month"*, *"day"*, *"hour"*, *"minute"*, *"second"* » in List order, do - 1. Set _expandedOptions_.[[<_field_>]] to *"numeric"*. - 1. Set _dateTimeFormat_.[[Pattern]] to _pattern_GetDateTimeFormatPattern(_matcher_, _expandedOptions_, _formats_, _hc_). + 1. Set _dateTimeFormat_.[[Pattern]] to _pattern__bestFormat_.[[pattern]]. 1. For each row in , except the header row, in table order, do 1. Let _limitedOptions_ be a new Record. 1. Let _needDefaults_ be *true*. @@ -434,6 +393,12 @@

PartitionDateTimePattern ( _dateTimeFormat_, _x_ )

1. Perform ! CreateDataPropertyOrThrow(_nf2Options_, *"minimumIntegerDigits"*, 2). 1. Perform ! CreateDataPropertyOrThrow(_nf2Options_, *"useGrouping"*, *false*). 1. Let _nf2_ be ? Construct(%NumberFormat%, « _locale_, _nf2Options_ »). + 1. Let _fractionalSecondDigits_ be _dateTimeFormat_.[[FractionalSecondDigits]]. + 1. If _fractionalSecondDigits_ is not *undefined*, then + 1. Let _nf3Options_ be ObjectCreate(*null*). + 1. Perform ! CreateDataPropertyOrThrow(_nf3Options_, *"minimumIntegerDigits"*, _fractionalSecondDigits_). + 1. Perform ! CreateDataPropertyOrThrow(_nf3Options_, *"useGrouping"*, *false*). + 1. Let _nf3_ be ? Construct(%NumberFormat%, « _locale_, _nf3Options_ »). 1. Let _tm_ be ToLocalTime(_x__epochNanoseconds_, _dateTimeFormat_.[[Calendar]], _dateTimeFormat_.[[TimeZone]]). 1. Let _result_ be a new empty List. 1. Let _patternParts_ be PartitionPattern(_dateTimeFormat_.[[Pattern]]_pattern_). @@ -441,6 +406,11 @@

PartitionDateTimePattern ( _dateTimeFormat_, _x_ )

1. Let _p_ be _patternPart_.[[Type]]. 1. If _p_ is *"literal"*, then 1. Append a new Record { [[Type]]: *"literal"*, [[Value]]: _patternPart_.[[Value]] } as the last element of the list _result_. + 1. Else if _p_ is equal to *"fractionalSecondDigits"*, then + 1. Let _v_ be _tm_.[[Millisecond]]. + 1. Let _v_ be floor(_v_ × 10( _fractionalSecondDigits_ - 3 )). + 1. Let _fv_ be FormatNumeric(_nf3_, _v_). + 1. Append a new Record { [[Type]]: *"fractionalSecond"*, [[Value]]: _fv_ } as the last element of _result_. 1. Else if _p_ matches a Property column of the row in , then 1. Let _f_ be the value of _dateTimeFormat_'s internal slot whose name is the Internal Slot column of the matching row_pattern_.[[<_p_>]]. 1. Let _v_ be the value of _tm_'s field whose name is the Internal Slot column of the matching row. @@ -461,7 +431,7 @@

PartitionDateTimePattern ( _dateTimeFormat_, _x_ )

1. Else if _f_ is *"2-digit"*, then 1. Let _fv_ be FormatNumeric(_nf2_, _v_). 1. If the *"length"* property of _fv_ is greater than 2, let _fv_ be the substring of _fv_ containing the last two characters. - 1. Else if _f_ is *"narrow"*, *"short"*, or *"long"*, then let _fv_ be a String value representing _f_ in the desired form; the String value depends upon the implementation and the effective locale and calendar of _dateTimeFormat_. If _p_ is *"month"*, then the String value may also depend on whether _dateTimeFormat_ has a [[Day]]_pattern_ has a [[day]] internal slot. If _p_ is *"timeZoneName"*, then the String value may also depend on the value of the [[InDST]] field of _tm_. If _p_ is *"era"*, then the String value may also depend on whether _dateTimeFormat_ has a [[Era]]_pattern_ has a [[era]] internal slot and if the implementation does not have a localized representation of _f_, then use _f_ itself. + 1. Else if _f_ is *"narrow"*, *"short"*, or *"long"*, then let _fv_ be a String value representing _v_ in the form given by _f_; the String value depends upon the implementation and the effective locale and calendar of _dateTimeFormat_. If _p_ is *"month"*, then the String value may also depend on whether _dateTimeFormat_ has a [[Day]]_pattern_ has a [[day]] internal slot. If _p_ is *"timeZoneName"*, then the String value may also depend on the value of the [[InDST]] field of _tm_. If _p_ is *"era"*, then the String value may also depend on whether _dateTimeFormat_ has a [[Era]]_pattern_ has a [[era]] internal slot and if the implementation does not have a localized representation of _f_, then use _f_ itself. 1. Append a new Record { [[Type]]: _p_, [[Value]]: _fv_ } as the last element of the list _result_. 1. Else if _p_ is equal to *"ampm"*, then 1. Let _v_ be _tm_.[[Hour]]. @@ -585,10 +555,9 @@

ToLocalTime ( _t_, _calendar_, _timeZone_ )

1. Let _timeZoneOffset_ be the value calculated according to LocalTZA(_t_, *true*) where the local time zone is replaced with timezone _timeZone_. 1. Let _timeZoneOffset_ be ! GetIANATimeZoneOffsetNanoseconds(_t_, _timeZone_). 1. Let _tz_ be the time value _t_ + _timeZoneOffset_. - 1. Return a record with fields calculated from _tz_ according to . + 1. Return a record with fields calculated from _tz_ according to . 1. Else, - 1. Return a record with the fields of Column 1 of calculated from _t_ for the given _calendar_ and _timeZone_. The calculations should use best available information about the specified _calendar_ and _timeZone_, including current and historical information about time zone offsets from UTC and daylight saving time rules. - Given the same values of _t_, _calendar_, and _timeZone_, the result must be the same for the lifetime of the surrounding agent. + 1. Return a record with the fields of Column 1 of calculated from _t_ for the given _calendar_ and _timeZone_. The calculations should use best available information about the specified _calendar_ and _timeZone_, including current and historical information about time zone offsets from UTC and daylight saving time rules. Given the same values of _t_, _calendar_, and _timeZone_, the result must be the same for the lifetime of the surrounding agent. @@ -664,6 +633,13 @@

ToLocalTime ( _t_, _calendar_, _timeZone_ )

! SecFromTime(_tz_ / 106) + + [[Millisecond]] + + `msFromTime(tz)` specified in ES2021's Hours, Minutes, Second, and Milliseconds + ! msFromTime(_tz_ / 106) + + [[Nanosecond]] _tz_ modulo 109 @@ -734,6 +710,9 @@

Intl.DateTimeFormat.prototype.resolvedOptions ( )

1. Else, 1. Assert: the Location value of the current row is ~pattern~. 1. Let _v_ be the value of _dtf_.[[Pattern]]'s internal slot whose name is the Internal Slot value of the current row. + 1. If the Internal Slot value of the current row is an Internal Slot value in , then + 1. If _dtf_.[[DateStyle]] is not *undefined* or _dtf_.[[TimeStyle]] is not *undefined*, then + 1. Let _v_ be *undefined*. 1. If _v_ is not *undefined*, then 1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_). 1. Return _options_. @@ -804,6 +783,11 @@

Intl.DateTimeFormat.prototype.resolvedOptions ( )

*"day"* ~pattern~ + + [[DayPeriod]][[dayPeriod]] + *"dayPeriod"* + ~pattern~ + [[Hour]][[hour]] *"hour"* @@ -819,10 +803,25 @@

Intl.DateTimeFormat.prototype.resolvedOptions ( )

*"second"* ~pattern~ + + [[FractionalSecondDigits]][[fractionalSecondDigits]] + *"fractionalSecondDigits"* + ~pattern~ + [[TimeZoneName]][[timeZoneName]] *"timeZoneName"* ~pattern~ + + [[DateStyle]] + *"dateStyle"* + ~object~ + + + [[TimeStyle]] + *"timeStyle"* + ~object~ +
@@ -861,8 +860,10 @@

  • [[NumberingSystem]] is a String value with the *"type"* given in Unicode Technical Standard 35 for the numbering system used for formatting.
  • [[TimeZone]] is a String value with the IANA time zone name of the time zone used for formatting.
  • -
  • [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]] are each either *undefined*, indicating that the component is not used for formatting, or one of the String values given in , indicating how the component should be presented in the formatted output.
  • +
  • [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]] are each either *undefined*, indicating that the component is not used for formatting, or one of the String values given in , indicating how the component should be presented in the formatted output.
  • +
  • [[FractionalSecondDigits]] is either *undefined* or a positive, non-negative integer Number value indicating the fraction digits to be used for fractional seconds. Numbers will be rounded or padded with trailing zeroes if necessary.
  • [[HourCycle]] is a String value indicating whether the 12-hour format (*"h11"*, *"h12"*) or the 24-hour format (*"h23"*, *"h24"*) should be used. *"h11"* and *"h23"* start with hour 0 and go up to 11 and 23 respectively. *"h12"* and *"h24"* start with hour 1 and go up to 12 and 24. [[HourCycle]] is only used when [[Hour]] is not *undefined*.
  • +
  • [[DateStyle]], [[TimeStyle]] are each either *undefined*, or a String value with values *"full"*, *"long"*, *"medium"*, or *"short"*.
  • [[Pattern]], [[TemporalPlainDatePattern]], [[TemporalPlainYearMonthPattern]], [[TemporalPlainMonthDayPattern]], [[TemporalPlainTimePattern]], [[TemporalPlainDateTimePattern]], [[TemporalInstantPattern]], and [[TemporalZonedDateTimePattern]] are is a String valuerecords containing at least a [[pattern]] field as described in .