Skip to content

Commit

Permalink
DateTimeFormat.formatToParts() first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
Zibi Braniecki committed Jan 28, 2016
1 parent 9887d9b commit 77d7832
Showing 1 changed file with 138 additions and 14 deletions.
152 changes: 138 additions & 14 deletions spec/datetimeformat.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ <h1>InitializeDateTimeFormat (dateTimeFormat, locales, options)</h1>
1. Let _pattern_ be Get(_bestFormat_, *"pattern"*).
1. Set _dateTimeFormat_.[[pattern]] to _pattern_.
1. Set _dateTimeFormat_.[[boundFormat]] to *undefined*.
1. Set _dateTimeFormat_.[[boundFormatToParts]] to *undefined*.
1. Set _dateTimeFormat_.[[initializedDateTimeFormat]] to *true*.
1. Return _dateTimeFormat_.
</emu-alg>
Expand Down Expand Up @@ -224,55 +225,158 @@ <h1>DateTime Format Functions</h1>
1. Return FormatDateTime(_dtf_, _x_).
</emu-alg>

<emu-note>
The function returned by [[Get]] is bound to this DateTimeFormat object so that it can be passed directly to Array.prototype.map or other functions.
</emu-note>

<p>
The *length* property of a DateTime format function is 1.
</p>
</emu-clause>

<emu-clause id="sec-formatdatetime" aoid="FormatDateTime">
<h1>FormatDateTime (dateTimeFormat, x)</h1>
<emu-clause id="sec-datetime-formatToParts-functions">
<h1>DateTime FormatToParts Functions</h1>

<p>
When the FormatDateTime abstract operation is called with arguments _dateTimeFormat_ (which must be an object initialized as a DateTimeFormat) and _x_ (which must be a Number value), it returns a String value representing _x_ (interpreted as a time value as specified in ES2015, 20.3.1.1) according to the effective locale and the formatting options of _dateTimeFormat_. This abstract operation functions as follows:
A DateTime formatToParts function is an anonymous function that optionally takes an argument _date_. It performs the following steps:
</p>

<emu-alg>
1. Let _dtf_ be the *this* value.
1. Assert: Type(_dtf_) is Object and _dtf_ has an [[initializedDateTimeFormat]] internal slot whose value is *true*.
1. If _date_ is not provided or is *undefined*, then
1. Let _x_ be *%Date_now%*().
1. Else,
1. Let _x_ be ? ToNumber(_date_).
1. Return FormatToPartsDateTime(_dtf_, _x_).
</emu-alg>

<emu-note>
The function returned by [[Get]] is bound to this DateTimeFormat object so that it can be passed directly to Array.prototype.map or other functions.
</emu-note>

<p>
The value of the [[Set]] attribute is *undefined*.
</p>
</emu-clause>

<emu-clause id="alg-CreateDateTimeParts">

<h1>CreateDateTimeParts(dateTimeFormat, x)</h1>

<p>
The CreateDateTimeParts abstract operation is called with arguments _dateTimeFormat_ (which must be an object initialized as a DateTimeFormat) and _x_ (which must be a Number value), and performs the following steps:
</p>

<emu-alg aoid="CreateDateTimeParts">
1. If _x_ is not a finite Number, throw a *RangeError* exception.
1. Let _locale_ be the value of _dateTimeFormat_.[[locale]].
1. Let _nf_ be ? Construct(%NumberFormat%, « [locale], {useGrouping: *false*} »).
1. Let _nf2_ be ? Construct(%NumberFormat%, « [locale], {minimumIntegerDigits: 2, useGrouping: *false*} »).
1. Let _tm_ be ToLocalTime(_x_, _dateTimeFormat_.[[calendar]], _dateTimeFormat_.[[timeZone]]).
1. Let _result_ be the value of the _dateTimeFormat_.[[pattern]].
1. For each row of <emu-xref href="#table-3">Table 3</emu-xref>, except the header row, do:
1. If _dateTimeFormat_ has an internal slot with the name given in the Property column of the row, then
1. Let _p_ be the name given in the Property column of the row.
1. Let _pattern_ be the value of the _dateTimeFormat_.[[pattern]].
1. Let _result_ be a new empty List.
1. Let _index_ be 0.
1. Let _beginIndex_ be Call(*%StringProto_indexOf%*, _pattern_, "{", *0*).
1. Let _endIndex_ be 0.
1. Repeat while _beginIndex_ is an integer index into _pattern_:
1. Set _endIndex_ to Call(*%StringProto_indexOf%*, _pattern_, "}", _beginIndex_)
1. If _endIndex_ is *false*, throw new Error exception.
1. If _beginIndex_ is greater than _index_, then:
1. Let _separator_ be a new Record.
1. Let _separatorValue_ be a substring of _pattern_ from position _index_, inclusive, to position _beginIndex_, exclusive.
1. Add new part record { [[type]]: "separator", [[value]]: _separatorValue_ } as a new element of the list _result_.
1. Let _p_ be the substring of _pattern_ from position _beginIndex_, exclusive, to position _endIndex_, exclusive.
1. If _p_ matches a Property column of the row in Table 3, then:
1. Let _f_ be the value of the [[<_p_>]] internal slot of _dateTimeFormat_.
1. Let _v_ be the value of _tm_.[[<_p_>]].
1. If _p_ is *"year"* and _v_ ≤ 0, let _v_ be 1 - _v_.
1. If _p_ is *"month"*, increase _v_ by 1.
1. If _p_ is *"hour"* and the value of _dateTimeFormat_.[[hour12]] is *true*, then
1. Let _v_ be _v_ modulo 12.
1. If _v_ is equal to the value of _tm_.[[<_p_>]], let _pm_ be *false*; else let _pm_ be *true*.
1. If _v_ is 0 and the value of _dateTimeFormat_.[[hourNo0]] is *true*, let _v_ be 12.
1. If _f_ is *"numeric"*, then
1. Let _fv_ be FormatNumber(_nf_, _v_).
1. Else if f is *"2-digit"*, then
1. Let _fv_ be FormatNumber(_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]] internal slot. If _p_ is *"timeZoneName"*, then the String value may also depend on the value of the [[inDST]] field of _tm_, and if the implementation does not have a localized representation of _f_, then use _f_ itself.
1. Replace the substring of _result_ that consists of *"{"*, p, and *"}"*, with _fv_.
1. If _dateTimeFormat_.[[hour12]] is *true*, then
1. If _pm_ is *true*, then
1. Let _fv_ be an implementation and locale dependent String value representing "post meridiem";
1. Add new part record { [[type]]: _p_, [[value]]: _fv_ } as a new element of the list _result_.
1. Else if _p_ is equal "ampm", then:
1. Let _v_ be the value of _tm_.[[hour]].
1. If _v_ is greater than 11, then:
1. Let _fv_ be an implementation and locale dependent String value representing "post meridiem";
1. Else,
1. Let _fv_ be an implementation and locale dependent String value representing "ante meridiem".
1. Add new part record { [[type]]: "dayperiod", [[value]]: _fv_ } as a new element of the list _result_.
1. Else,
1. Let _fv_ be an implementation and locale dependent String value representing "ante meridiem".
1. Replace the substring of _result_ that consists of *"{ampm}"*, with _fv_.
1. <emu-note>Unknown token</emu-note>
1. Let _separatorValue_ be the substring of _pattern_ from position _beginIndex_, inclusive, to position _endIndex_, inclusive.
1. Add new part record { [[type]]: "separtor", [[value]]: _separatorValue_ } as a new element of the list _result_.
1. Set _index_ to _endIndex_ + 1.
1. Set _beginIndex_ to Call(*%StringProto_indexOf%*, _pattern_, "}", _index_)
1. If _endIndex_ is less than _S_, then:
1. Let _separator_ to be a new Record.
1. Let _separatorValue_ be the substring of _pattern_ from position _endIndex_, exclusive, to position _S_, exclusive.
1. Add new part record { [[type]]: "separator", [[value]]: _separatorValue_ } as a new element of the list _result_.
1. Return _result_.
</emu-alg>

<emu-note>
CreateDateTimeParts abstract operation interpretes _x_ as a time value as specified in ES2015, 20.3.1.1; and create the corresponding parts according to the effective locale and the formatting options of _dateTimeFormat_.
</emu-note>

<emu-note>
It is recommended that implementations use the locale and calendar dependent strings provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>), and use CLDR "abbreviated" strings for DateTimeFormat "short" strings, and CLDR "wide" strings for DateTimeFormat "long" strings.
</emu-note>

<emu-note>
It is recommended that implementations use the time zone information of the IANA Time Zone Database.
</emu-note>

</emu-clause>

<emu-clause id="alg-FormatDateTime">

<h1>FormatDateTime(dateTimeFormat, x)</h1>

<p>
The FormatDateTime abstract operation is called with arguments _dateTimeFormat_ (which must be an object initialized as a DateTimeFormat) and _x_ (which must be a Number value), and performs the following steps:
</p>

<emu-alg aoid="DateTimeFormat">
1. Let _parts_ be CreateDateTimeParts(_dateTimneFormat_, _x_).
1. Let _result_ be an empty string.
1. For each _part_ in _parts_, do:
1. Set _result_ to a String value produced by concatenating _result_ and _part_.[[value]].
1. Return _result_.
</emu-alg>

</emu-clause>

<emu-clause id="alg-FormatToPartDateTime">

<h1>FormatToPartDateTime(dateTimeFormat, x)</h1>

<p>
The FormatToPartDateTime abstract operation is called with arguments _dateTimeFormat_ (which must be an object initialized as a DateTimeFormat) and _x_ (which must be a Number value), and performs the following steps:
</p>

<emu-alg aoid="DateTimeFormatToParts">
1. Let _parts_ be CreateDateTimeParts(_dateTimneFormat_, _x_).
1. Let _result_ be ArrayCreate(0).
1. Let _n_ be 0.
1. For each _part_ in _parts_, do:
1. Let _O_ be ObjectCreate(%ObjectPrototype%).
1. Let _typeDesc_ be the PropertyDescriptor{[[Value]]: _part_.[[type]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
1. Perform ? DefinePropertyOrThrow(_O_, "type", _typeDesc_).
1. Let _valueDesc_ be the PropertyDescriptor{[[Value]]: _part_.[[value]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
1. Perform ? DefinePropertyOrThrow(_O_, "value", _valueDesc_).
1. Perform ? CreateDataProperty(_result_, ? ToString(_n_), _O_).
1. Increment _n_ by 1.
1. Return _result_.
</emu-alg>

</emu-clause>

<emu-clause id="sec-tolocaltime" aoid="ToLocalTime">
Expand Down Expand Up @@ -452,6 +556,26 @@ <h1>get Intl.DateTimeFormat.prototype.format</h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-Intl.DateTimeFormat.prototype.formatToParts">
<h1>get Intl.DateTimeFormat.prototype.formatToParts</h1>

<p>
Intl.DateTimeFormat.prototype.formatToParts is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:
</p>

<emu-alg>
1. Let _dtf_ be *this* value.
1. If Type(_dtf_) is not Object, throw a *TypeError* exception.
1. If _dtf_ does not have a [[boundFormatToParts]] internal slot, throw a *TypeError* exception.
1. If the [[boundFormatToParts]] internal slot of _dtf_ is *undefined*, then
1. Let _F_ be a new built-in function object as defined in DateTime Format Functions (<emu-xref href="#sec-datetime-formatToParts-functions"></emu-xref>).
1. The value of _F_’s *length* property is 1.
1. Let _bf_ be BoundFunctionCreate(_F_, _dft_).
1. Set _dtf_.[[boundFormatToParts]] to _bf_.
1. Return _dtf_.[[boundFormatToParts]].
</emu-alg>
</emu-clause>

<emu-clause id="sec-Intl.DateTimeFormat.prototype.resolvedOptions">
<h1>Intl.DateTimeFormat.prototype.resolvedOptions ()</h1>

Expand Down

0 comments on commit 77d7832

Please sign in to comment.