Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normative: Read date-time options only once when creating DateTimeFormat objects #709

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 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
78 changes: 34 additions & 44 deletions spec/datetimeformat.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ <h1>Intl.DateTimeFormat ( [ _locales_ [ , _options_ ] ] )</h1>

<emu-alg>
1. If NewTarget is *undefined*, let _newTarget_ be the active function object, else let _newTarget_ be NewTarget.
1. Let _dateTimeFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%DateTimeFormat.prototype%"*, &laquo; [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[FractionalSecondDigits]], [[TimeZoneName]], [[HourCycle]], [[DateStyle]], [[TimeStyle]], [[Pattern]], [[RangePatterns]], [[BoundFormat]] &raquo;).
1. Perform ? InitializeDateTimeFormat(_dateTimeFormat_, _locales_, _options_).
1. Let _dateTimeFormat_ be ? CreateDateTimeFormat(_newTarget_, _locales_, _options_, ~any~, ~date~).
anba marked this conversation as resolved.
Show resolved Hide resolved
1. If the implementation supports the normative optional constructor mode of <emu-xref href="#legacy-constructor"></emu-xref>, then
1. Let _this_ be the *this* value.
1. Return ? ChainDateTimeFormat(_dateTimeFormat_, NewTarget, _this_).
Expand All @@ -38,20 +37,28 @@ <h1>ChainDateTimeFormat ( _dateTimeFormat_, _newTarget_, _this_ )</h1>
</emu-normative-optional>
</emu-clause>

<emu-clause id="sec-initializedatetimeformat" aoid="InitializeDateTimeFormat">
<h1>InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )</h1>
<emu-clause id="sec-createdatetimeformat" type="abstract operation" oldids="sec-initializedatetimeformat,sec-todatetimeoptions">
<h1>
CreateDateTimeFormat (
_newTarget_: a constructor,
_locales_: an ECMAScript language value,
_options_: an ECMAScript language value,
_required_: ~date~, ~time~, or ~any~,
_defaults_: ~date~, ~time~, or ~all~,
): either a normal completion containing a DateTimeFormat object or a throw completion
anba marked this conversation as resolved.
Show resolved Hide resolved
</h1>

<p>
The abstract operation InitializeDateTimeFormat accepts the arguments _dateTimeFormat_ (which must be an object), _locales_, and _options_. It initializes _dateTimeFormat_ as a DateTimeFormat object. This abstract operation functions as follows:
</p>
<dl class="header">
</dl>

<p>
The following algorithm refers to the `type` nonterminal from <a href="https://www.unicode.org/reports/tr35/#Unicode_locale_identifier">UTS 35's Unicode Locale Identifier grammar</a>.
</p>

<emu-alg>
1. Let _dateTimeFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%DateTimeFormat.prototype%"*, &laquo; [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[FractionalSecondDigits]], [[TimeZoneName]], [[HourCycle]], [[DateStyle]], [[TimeStyle]], [[Pattern]], [[RangePatterns]], [[BoundFormat]] &raquo;).
1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
1. Set _options_ to ? ToDateTimeOptions(_options_, *"any"*, *"date"*).
1. Set _options_ to ? CoerceOptionsToObject(_options_).
1. Let _opt_ be a new Record.
1. Let _matcher_ be ? GetOption(_options_, *"localeMatcher"*, ~string~, &laquo; *"lookup"*, *"best fit"* &raquo;, *"best fit"*).
1. Set _opt_.[[localeMatcher]] to _matcher_.
Expand Down Expand Up @@ -116,9 +123,28 @@ <h1>InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )</h1>
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 _dataLocaleData_.[[styles]].[[&lt;_resolvedCalendar_&gt;]].
1. Let _bestFormat_ be DateTimeStyleFormat(_dateStyle_, _timeStyle_, _styles_).
1. Else,
1. Let _needDefaults_ be *true*.
1. If _required_ is ~date~ or ~any~, then
1. For each property name _prop_ of &laquo; *"weekday"*, *"year"*, *"month"*, *"day"* &raquo;, do
1. Let _value_ be _formatOptions_.[[&lt;_prop_&gt;]].
1. If _value_ is not *undefined*, let _needDefaults_ be *false*.
1. If _required_ is ~time~ or ~any~, then
1. For each property name _prop_ of &laquo; *"dayPeriod"*, *"hour"*, *"minute"*, *"second"*, *"fractionalSecondDigits"* &raquo;, do
1. Let _value_ be _formatOptions_.[[&lt;_prop_&gt;]].
1. If _value_ is not *undefined*, let _needDefaults_ be *false*.
1. If _needDefaults_ is *true* and _defaults_ is either ~date~ or ~all~, then
1. For each property name _prop_ of &laquo; *"year"*, *"month"*, *"day"* &raquo;, do
1. Set _formatOptions_.[[&lt;_prop_&gt;]] to *"numeric"*.
1. If _needDefaults_ is *true* and _defaults_ is either ~time~ or ~all~, then
1. For each property name _prop_ of &laquo; *"hour"*, *"minute"*, *"second"* &raquo;, do
1. Set _formatOptions_.[[&lt;_prop_&gt;]] to *"numeric"*.
1. Let _formats_ be _dataLocaleData_.[[formats]].[[&lt;_resolvedCalendar_&gt;]].
1. If _matcher_ is *"basic"*, then
1. Let _bestFormat_ be BasicFormatMatcher(_formatOptions_, _formats_).
Expand Down Expand Up @@ -746,42 +772,6 @@ <h1>Abstract Operations for DateTimeFormat Objects</h1>
</table>
</emu-table>

<emu-clause id="sec-todatetimeoptions" aoid="ToDateTimeOptions">
<h1>ToDateTimeOptions ( _options_, _required_, _defaults_ )</h1>

<p>
When the ToDateTimeOptions abstract operation is called with arguments _options_, _required_, and _defaults_, the following steps are taken:
</p>

<emu-alg>
1. If _options_ is *undefined*, let _options_ be *null*; otherwise let _options_ be ? ToObject(_options_).
1. Let _options_ be OrdinaryObjectCreate(_options_).
1. Let _needDefaults_ be *true*.
1. If _required_ is *"date"* or *"any"*, then
1. For each property name _prop_ of &laquo; *"weekday"*, *"year"*, *"month"*, *"day"* &raquo;, do
1. Let _value_ be ? Get(_options_, _prop_).
1. If _value_ is not *undefined*, let _needDefaults_ be *false*.
1. If _required_ is *"time"* or *"any"*, then
1. For each property name _prop_ of &laquo; *"dayPeriod"*, *"hour"*, *"minute"*, *"second"*, *"fractionalSecondDigits"* &raquo;, do
1. Let _value_ be ? Get(_options_, _prop_).
1. If _value_ is not *undefined*, let _needDefaults_ be *false*.
1. Let _dateStyle_ be ? Get(_options_, *"dateStyle"*).
1. Let _timeStyle_ be ? Get(_options_, *"timeStyle"*).
1. If _dateStyle_ is not *undefined* or _timeStyle_ is not *undefined*, let _needDefaults_ be *false*.
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. If _needDefaults_ is *true* and _defaults_ is either *"date"* or *"all"*, then
1. For each property name _prop_ of &laquo; *"year"*, *"month"*, *"day"* &raquo;, do
1. Perform ? CreateDataPropertyOrThrow(_options_, _prop_, *"numeric"*).
1. If _needDefaults_ is *true* and _defaults_ is either *"time"* or *"all"*, then
1. For each property name _prop_ of &laquo; *"hour"*, *"minute"*, *"second"* &raquo;, do
1. Perform ? CreateDataPropertyOrThrow(_options_, _prop_, *"numeric"*).
1. Return _options_.
</emu-alg>
</emu-clause>

<emu-clause id="sec-date-time-style-format" aoid="DateTimeStyleFormat">
<h1>DateTimeStyleFormat ( _dateStyle_, _timeStyle_, _styles_ )</h1>
<p>The DateTimeStyleFormat abstract operation accepts arguments _dateStyle_ and _timeStyle_, which are each either *undefined*, *"full"*, *"long"*, *"medium"*, or *"short"*, at least one of which is not *undefined*, and _styles_, which is a record from %DateTimeFormat%.[[LocaleData]].[[&lt;_locale_&gt;]].[[styles]].[[&lt;_calendar_&gt;]] for some locale _locale_ and calendar _calendar_. It returns the appropriate format record for date time formatting based on the parameters.</p>
Expand Down
9 changes: 3 additions & 6 deletions spec/locale-sensitive-functions.html
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,7 @@ <h1>Date.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )</h1>
<emu-alg>
1. Let _x_ be ? thisTimeValue(*this* value).
1. If _x_ is *NaN*, return *"Invalid Date"*.
1. Let _options_ be ? ToDateTimeOptions(_options_, *"any"*, *"all"*).
1. Let _dateFormat_ be ? Construct(%DateTimeFormat%, &laquo; _locales_, _options_ &raquo;).
1. Let _dateFormat_ be ? CreateDateTimeFormat(%DateTimeFormat%, _locales_, _options_, ~any~, ~all~).
1. Return ? FormatDateTime(_dateFormat_, _x_).
</emu-alg>
</emu-clause>
Expand All @@ -222,8 +221,7 @@ <h1>Date.prototype.toLocaleDateString ( [ _locales_ [ , _options_ ] ] )</h1>
<emu-alg>
1. Let _x_ be ? thisTimeValue(*this* value).
1. If _x_ is *NaN*, return *"Invalid Date"*.
1. Let _options_ be ? ToDateTimeOptions(_options_, *"date"*, *"date"*).
1. Let _dateFormat_ be ? Construct(%DateTimeFormat%, &laquo; _locales_, _options_ &raquo;).
1. Let _dateFormat_ be ? CreateDateTimeFormat(%DateTimeFormat%, _locales_, _options_, ~date~, ~date~).
1. Return ? FormatDateTime(_dateFormat_, _x_).
</emu-alg>
</emu-clause>
Expand All @@ -242,8 +240,7 @@ <h1>Date.prototype.toLocaleTimeString ( [ _locales_ [ , _options_ ] ] )</h1>
<emu-alg>
1. Let _x_ be ? thisTimeValue(*this* value).
1. If _x_ is *NaN*, return *"Invalid Date"*.
1. Let _options_ be ? ToDateTimeOptions(_options_, *"time"*, *"time"*).
1. Let _timeFormat_ be ? Construct(%DateTimeFormat%, &laquo; _locales_, _options_ &raquo;).
1. Let _timeFormat_ be ? CreateDateTimeFormat(%DateTimeFormat%, _locales_, _options_, ~time~, ~time~).
1. Return ? FormatDateTime(_timeFormat_, _x_).
</emu-alg>
</emu-clause>
Expand Down