diff --git a/.gitignore b/.gitignore
index 1c8cdd1..7bd1000 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,6 @@ jspm_packages
yarn.lock
package-lock.json
npm-shrinkwrap.json
+
+
+out.html
diff --git a/README.md b/README.md
index 24cafe4..f32bf3c 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,169 @@
Intl.NumberFormat Unified API Proposal
======================================
-## Motivation
+This proposal adds **measurement units**, **compact decimal notation**, and other localized number formatting features to Intl.NumberFormat.
-There are many requests for adding number-formatting-related features to ECMA 402. A few of them include:
+[TC39 Stage 2 Proposal](https://docs.google.com/presentation/d/1_1D15PWniTlbLu1BOU9aDf5H87Ecq85i0CuLl5KA4DE/edit?usp=sharing)
-- tc39/ecma402#200
-- tc39/ecma402#186
-- tc39/ecma402#164
-- tc39/ecma402#163
-- tc39/ecma402#95
-- tc39/ecma402#91
-- tc39/ecma402#37
-- tc39/ecma402#32
+[TC39 Stage 3 Proposal](https://docs.google.com/presentation/d/1BljVP4ENAqJt3CLXKapq_39Gr5RG6f1h9SQ_tsP7V8Y/edit?usp=sharing)
-Rather than complicate `Intl` with more subclasses with heavilly overlapping functionality, this proposal is to restructure the spec of `Intl.NumberFormat` to make it more easilly support additional features in a "unified" way.
+[View Spec](https://tc39.github.io/proposal-unified-intl-numberformat/)
+
+## Background / Motivation
+
+There are many requests for adding number-formatting-related features to ECMA-402 (the JavaScript Intl standard library). These include:
+
+- [Expose narrow currency symbol](https://github.com/tc39/ecma402/issues/200) -- Section I
+- [Clarification on behavior of SetNumberFormatDigitOptions](https://github.com/tc39/ecma402/issues/244) -- Section I
+- [Add measure unit formatting](https://github.com/tc39/ecma402/issues/32) -- Section II
+- [Add compact decimal notation](https://github.com/tc39/ecma402/issues/37) -- Section III
+- [Add scientific notation](https://github.com/tc39/ecma402/issues/164) -- Section III
+- [Add currency accounting format](https://github.com/tc39/ecma402/issues/186) -- Section IV
+- [Add option to force sign](https://github.com/tc39/ecma402/issues/163) -- Section IV
+
+These features are important to both end users and to Google. Since most of these features require carrying along large amounts of locale data for proper i18n support, exposing these features via a JavaScript API reduces bandwidth and lowers the barrier to entry for i18n best practices.
+
+Rather than complicate `Intl` with more constructors with heavilly overlapping functionality, this proposal is to restructure the spec of `Intl.NumberFormat` to make it more easilly support additional features in a "unified" way.
+
+Additional background: [prior discussion](https://github.com/tc39/ecma402/issues/215)
+
+## I. Units
+
+Units of measurement can be formatted as follows:
+
+```javascript
+(299792458).toLocaleString("en-US", {
+ style: "unit",
+ unit: "meter-per-second",
+ unitDisplay: "short"
+});
+// ==> "299,792,458 m/s"
+```
+
+The syntax was discussed in #3.
+
+- `style` receives the string value "unit"
+- `unit` receives a string core unit identifier, defined in [UTS #35, Part 2, Section 6](http://unicode.org/reports/tr35/tr35-general.html#Unit_Elements). See also the [full list of unit identifiers](https://github.com/unicode-org/cldr/blob/master/common/validity/unit.xml).
+- `unitDisplay`, named after the corresponding setting for currencies, `currencyDisplay`, takes either "narrow", "short", or "long".
+
+## II. Scientific and Compact Notation
+
+Scientific and compact notation are represented by the new option `notation` and can be formatted as follows:
+
+```javascript
+(987654321).toLocaleString("en-US", {
+ notation: "scientific"
+});
+// ==> 9.877E8
+
+(987654321).toLocaleString("en-US", {
+ notation: "engineering"
+});
+// ==> 987.7E6
+
+(987654321).toLocaleString("en-US", {
+ notation: "compact",
+ compactDisplay: "long"
+});
+// ==> 987.7 million
+```
+
+The syntax was discussed in #5.
+
+- `notation` takes either "scientific", "engineering", "compact", or "plain"
+- `compactDisplay`, used only when `notation` is "compact", takes either "short" or "long"
+
+Rounding-related settings (min/max integer/fraction digits) are applied after the number is scaled according to the chosen notation.
+
+When `notation` is "compact" and there are no user-specified rounding options, a special compact notation rounding strategy is used: round to the nearest integer, but always keep 2 significant digits. For example, 123.4K rounds to 123K, and 1.234K rounds to 1.2K. The user can determine that the compact rounding strategy is being used in the *resolvedOptions* if `notation` is "compact" *and* none of the rounding settings are present.
+
+Notation styles are allowed to be combined with other options:
+
+```javascript
+(299792458).toLocaleString("en-US", {
+ notation: "scientific",
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ style: "unit",
+ unit: "meter-per-second"
+});
+// ==> 3.00E8 m/s
+```
+
+## III. Sign Display
+
+The sign can be displayed on positive numbers:
+
+```javascript
+(55).toLocaleString("en-US", {
+ signDisplay: "always"
+});
+// ==> +55
+```
+
+Currency accounting sign display is also supported via a new option. In many locales, accounting format means to wrap the number with parentheses instead of
+appending a minus sign. For example:
+
+```javascript
+(-100).toLocaleString("bn", {
+ style: "currency",
+ currency: "EUR",
+ currencySign: "accounting"
+});
+// ==> (১০০.০০€)
+```
+
+The syntax was discussed in #6:
+
+- `signDisplay`: "auto" (default), "always", "never", "exceptZero"
+ - See examples below.
+- `currencySign`: "standard" (default), "accounting"
+ - "accounting" enables the accounting format on currency values, as shown in the example above. "standard", the default value, disables accounting formats.
+
+Examples of signDisplay choices with Latin digits:
+
+signDisplay | -1 | -0 | 0 | 1
+----------- | --- | --- | --- | ---
+auto | -1 | -0 | 0 | 1
+always | -1 | -0 | +0 | +1
+never | 1 | 0 | 0 | 1
+exceptZero | -1 | -0 | 0 | +1
+
+Examples of signDisplay choices with Latin digits when `currencySign` is "accounting":
+
+signDisplay | -1 | -0 | 0 | 1
+----------- | ------ | ------ | ------ | ------
+auto | ($1.00) | ($0.00) | $0.00 | $1.00
+always | ($1.00) | ($0.00) | +$0.00 | +$1.00
+never | $1.00 | $0.00 | $0.00 | $1.00
+exceptZero | ($1.00) | ($0.00) | $0.00 | +$1.00
+
+As usual, this may be combined with other options.
+
+```javascript
+(0.55).toLocaleString("en-US", {
+ style: "percent",
+ signDisplay: "exceptZero"
+});
+// ==> +55%
+```
+
+## IV. Spec Cleanup
+
+Certain sections of the spec have been refactored with the following objectives:
+
+- Fix https://github.com/tc39/ecma402/issues/238 (currency long name has dependency on plural form, and the currency long name pattern has dependency on currencyWidth).
+- Move pattern resolution out of the constructor to keep all internal fields of NumberFormat locale-agnostic, making it easier to reason about behavior in the format method.
+- Fix https://github.com/tc39/proposal-unified-intl-numberformat/issues/2, to allow minimumIntegerDigits to control integer digit count when significant digits are used.
+
+In addition, one missing option is added to the existing `currencyDisplay` setting: "narrowSymbol", which uses the CLDR narrow-format symbol:
+
+```javascript
+(100).toLocaleString("en-CA", {
+ style: "currency",
+ currency: "USD",
+ currencyDisplay: "narrowSymbol"
+});
+// ==> "$100" (rather than "US$100")
+```
-Background: tc39/ecma402#215
diff --git a/index.html b/index.html
index ed4de39..7388218 100644
--- a/index.html
+++ b/index.html
@@ -1,1822 +1,21 @@
-
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 http://www.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:
-
-
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
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.
-
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.
-
-
-
\ No newline at end of file
+
+
+Unified Intl.NumberFormat Feature Proposal
+
+
+
+
Unified Intl.NumberFormat Feature Proposal
+
For more information on this proposal, see GitHub.
+
Spec Text
+
Section 6 (Identification of Locales, Currencies, and Time Zones)
+
diff --git a/package.json b/package.json
index a454e1c..b19d7a0 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,11 @@
"name": "template-for-proposals",
"description": "A repository template for ECMAScript proposals.",
"scripts": {
- "build": "ecmarkup spec.emu > index.html"
+ "build:sec6": "ecmarkup section6/locales-currencies-tz_proposed.html section6/locales-currencies-tz_proposed_out.html",
+ "build:sec6-diff": "ecmarkup section6/locales-currencies-tz_diff.html section6/locales-currencies-tz_diff_out.html",
+ "build:sec11": "ecmarkup section11/numberformat_proposed.html section11/numberformat_proposed_out.html",
+ "build:sec11-diff": "ecmarkup section11/numberformat_diff.html section11/numberformat_diff_out.html",
+ "build": "npm run build:sec6 && npm run build:sec6-diff && npm run build:sec11 && npm run build:sec11-diff"
},
"homepage": "https://github.com/tc39/template-for-proposals#readme",
"repository": {
diff --git a/numberformat_current.html b/section11/numberformat_current.html
similarity index 95%
rename from numberformat_current.html
rename to section11/numberformat_current.html
index 979c8f5..0e269cb 100644
--- a/numberformat_current.html
+++ b/section11/numberformat_current.html
@@ -14,22 +14,22 @@
SetNumberFormatDigitOptions ( _intlObj_, _options_, _mnfdDefault_, _mxfdDefa
1. Assert: Type(_intlObj_) is Object.
1. Assert: Type(_options_) is Object.
- 1. Assert: type(_mnfdDefault_) is Number.
- 1. Assert: type(_mxfdDefault_) is Number.
- 1. Let _mnid_ be ? GetNumberOption(_options_, `"minimumIntegerDigits,"`, 1, 21, 1).
+ 1. Assert: Type(_mnfdDefault_) is Number.
+ 1. Assert: Type(_mxfdDefault_) is Number.
+ 1. Let _mnid_ be ? GetNumberOption(_options_, `"minimumIntegerDigits"`, 1, 21, 1).
1. Let _mnfd_ be ? GetNumberOption(_options_, `"minimumFractionDigits"`, 0, 20, _mnfdDefault_).
1. Let _mxfdActualDefault_ be max( _mnfd_, _mxfdDefault_ ).
1. Let _mxfd_ be ? GetNumberOption(_options_, `"maximumFractionDigits"`, _mnfd_, 20, _mxfdActualDefault_).
1. Let _mnsd_ be ? Get(_options_, `"minimumSignificantDigits"`).
1. Let _mxsd_ be ? Get(_options_, `"maximumSignificantDigits"`).
- 1. Set _intlObj_.[[MinimumIntegerDigits]] to mnid.
- 1. Set _intlObj_.[[MinimumFractionDigits]] to mnfd.
- 1. Set _intlObj_.[[MaximumFractionDigits]] to mxfd.
+ 1. Set _intlObj_.[[MinimumIntegerDigits]] to _mnid_.
+ 1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfd_.
+ 1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfd_.
1. If _mnsd_ is not *undefined* or _mxsd_ is not *undefined*, then
1. Let _mnsd_ be ? DefaultNumberOption(_mnsd_, 1, 21, 1).
1. Let _mxsd_ be ? DefaultNumberOption(_mxsd_, _mnsd_, 21, 21).
- 1. Set _intlObj_.[[MinimumSignificantDigits]] to mnsd.
- 1. Set _intlObj_.[[MaximumSignificantDigits]] to mxsd.
+ 1. Set _intlObj_.[[MinimumSignificantDigits]] to _mnsd_.
+ 1. Set _intlObj_.[[MaximumSignificantDigits]] to _mxsd_.
@@ -143,7 +143,7 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
- 1. If _x_ is not *NaN* and _x_ < 0, then
+ 1. If _x_ is not *NaN* and _x_ < 0 or _x_ is *-0*, then
1. Let _x_ be -_x_.
1. Let _pattern_ be _numberFormat_.[[NegativePattern]].
1. Else,
@@ -160,9 +160,9 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _literal_ be a substring of _pattern_ from position _nextIndex_, inclusive, to position _beginIndex_, exclusive.
1. Append a new Record { [[Type]]: `"literal"`, [[Value]]: _literal_ } as the last element of _result_.
1. Let _p_ be the substring of _pattern_ from position _beginIndex_, exclusive, to position _endIndex_, exclusive.
- 1. If _p_ is equal `"number"`, then
+ 1. If _p_ is equal to `"number"`, then
1. If _x_ is *NaN*, then
- 1. Let _n_ be an ILD String value indicating the *NaN* value.
+ 1. Let _n_ be an implementation- and locale-dependent (ILD) String value indicating the *NaN* value.
1. Append a new Record { [[Type]]: `"nan"`, [[Value]]: _n_ } as the last element of _result_.
1. Else if _x_ is not a finite Number,
1. Let _n_ be an ILD String value indicating infinity.
@@ -182,7 +182,7 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _integer_ be _n_.
1. Let _fraction_ be *undefined*.
1. If the _numberFormat_.[[UseGrouping]] is *true*, then
- 1. Let _groupSepSymbol_ be the ILND String representing the grouping separator.
+ 1. Let _groupSepSymbol_ be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
1. Let _groups_ be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the _integer_.
1. Assert: The number of elements in _groups_ List is greater than 0.
1. Repeat, while _groups_ List is not empty
@@ -196,16 +196,16 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _decimalSepSymbol_ be the ILND String representing the decimal separator.
1. Append a new Record { [[Type]]: `"decimal"`, [[Value]]: _decimalSepSymbol_ } as the last element of _result_.
1. Append a new Record { [[Type]]: `"fraction"`, [[Value]]: _fraction_ } as the last element of _result_.
- 1. Else if _p_ is equal `"plusSign"`, then
+ 1. Else if _p_ is equal to `"plusSign"`, then
1. Let _plusSignSymbol_ be the ILND String representing the plus sign.
1. Append a new Record { [[Type]]: `"plusSign"`, [[Value]]: _plusSignSymbol_ } as the last element of _result_.
- 1. Else if _p_ is equal `"minusSign"`, then
+ 1. Else if _p_ is equal to `"minusSign"`, then
1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
1. Append a new Record { [[Type]]: `"minusSign"`, [[Value]]: _minusSignSymbol_ } as the last element of _result_.
- 1. Else if _p_ is equal `"percentSign"` and _numberFormat_.[[Style]] is `"percent"`, then
+ 1. Else if _p_ is equal to `"percentSign"` and _numberFormat_.[[Style]] is `"percent"`, then
1. Let _percentSignSymbol_ be the ILND String representing the percent sign.
1. Append a new Record { [[Type]]: `"percentSign"`, [[Value]]: _percentSignSymbol_ } as the last element of _result_.
- 1. Else if _p_ is equal `"currency"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Else if _p_ is equal to `"currency"` and _numberFormat_.[[Style]] is `"currency"`, then
1. Let _currency_ be _numberFormat_.[[Currency]].
1. Assert: _numberFormat_.[[CurrencyDisplay]] is `"code"`, `"symbol"` or `"name"`.
1. If _numberFormat_.[[CurrencyDisplay]] is `"code"`, then
@@ -216,8 +216,8 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _cd_ be an ILD string representing _currency_ in long form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
1. Else,
- 1. Let _literal_ be the substring of _pattern_ from position _beginIndex_, inclusive, to position _endIndex_, inclusive.
- 1. Append a new Record { [[Type]]: `"literal"`, [[Value]]: _literal_ } as the last element of _result_.
+ 1. Let _unknown_ be an ILND String based on _x_ and _p_.
+ 1. Append a new Record { [[Type]]: `"unknown"`, [[Value]]: _unknown_ } as the last element of _result_.
1. Set _nextIndex_ to _endIndex_ + 1.
1. Set _beginIndex_ to Call(%StringProto_indexOf%, _pattern_, « `"{"`, _nextIndex_ »).
1. If _nextIndex_ is less than _length_, then
@@ -608,6 +608,11 @@
get Intl.NumberFormat.prototype.format
1. Set _nf_.[[BoundFormat]] to _F_.
1. Return _nf_.[[BoundFormat]].
+
+
+ The returned function is bound to _nf_ so that it can be passed directly to `Array.prototype.map` or other functions.
+ This is considered a historical artefact, as part of a convention which is no longer followed for new features, but is preserved to maintain compatibility with existing programs.
+
@@ -638,7 +643,7 @@
Intl.NumberFormat.prototype.resolvedOptions ()
1. If Type(_nf_) is not Object, throw a *TypeError* exception.
1. Let _nf_ be ? UnwrapNumberFormat(_nf_).
1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).
- 1. For each row of , except the header row, in any order, do
+ 1. For each row of , except the header row, in table order, do
1. Let _p_ be the Property value of the current row.
1. Let _v_ be the value of _nf_'s internal slot whose name is the Internal Slot value of the current row.
1. If _v_ is not *undefined*, then
diff --git a/section11/numberformat_diff.html b/section11/numberformat_diff.html
new file mode 100644
index 0000000..dd7c971
--- /dev/null
+++ b/section11/numberformat_diff.html
@@ -0,0 +1,1045 @@
+
+
+ The abstract operation SetNumberFormatDigitOptions applies digit
+ options used for number formatting onto the intl object.
+
+
+ 1. Assert: Type(_intlObj_) is Object.
+ 1. Assert: Type(_options_) is Object.
+ 1. Assert: Type(_mnfdDefault_) is Number.
+ 1. Assert: Type(_mxfdDefault_) is Number.
+ 1. Let _mnid_ be ? GetNumberOption(_options_, `"minimumIntegerDigits"`, 1, 21, 1).
+ 1. Let _mnfd_ be ? GetNumberOption(_options_, `"minimumFractionDigits"`, 0, 20, _mnfdDefault_).
+ 1. Let _mxfdActualDefault_ be max( _mnfd_, _mxfdDefault_ ).
+ 1. Let _mxfd_ be ? GetNumberOption(_options_, `"maximumFractionDigits"`, _mnfd_, 20, _mxfdActualDefault_).
+ 1. Let _mnsd_ be ? Get(_options_, `"minimumSignificantDigits"`).
+ 1. Let _mxsd_ be ? Get(_options_, `"maximumSignificantDigits"`).
+ 1. Set _intlObj_.[[MinimumIntegerDigits]] to _mnid_.
+ 1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfd_.
+ 1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfd_.
+ 1. If _mnsd_ is not *undefined* or _mxsd_ is not *undefined*, then
+ 1. Set _intlObj_.[[RoundingType]] to `"significantDigits"`.
+ 1. Let _mnsd_ be ? DefaultNumberOption(_mnsd_, 1, 21, 1).
+ 1. Let _mxsd_ be ? DefaultNumberOption(_mxsd_, _mnsd_, 21, 21).
+ 1. Set _intlObj_.[[MinimumSignificantDigits]] to _mnsd_.
+ 1. Set _intlObj_.[[MaximumSignificantDigits]] to _mxsd_.
+ 1. Else If _mnfd_ is not *undefined* or _mxfd_ is not *undefined*, then
+ 1. Set _intlObj_.[[RoundingType]] to `"fractionDigits"`.
+ 1. Let _mnfd_ be ? DefaultNumberOption(_mnfd_, 0, 20, _mnfdDefault_).
+ 1. Let _mxfdActualDefault_ be max( _mnfd_, _mxfdDefault_ ).
+ 1. Let _mxfd_ be ? DefaultNumberOption(_mxfd_, _mnfd_, 20, _mxfdActualDefault_).
+ 1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfd_.
+ 1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfd_.
+ 1. Else If _intlObj_.[[Notation]] is `"compact"`, then
+ 1. Set _intlObj_.[[RoundingType]] to `"compactRounding"`.
+ 1. Else,
+ 1. Set _intlObj_.[[RoundingType]] to `"fractionDigits"`.
+ 1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfdDefault_.
+ 1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfdDefault_.
+
+
+
+
+
+ The abstract operation InitializeNumberFormat accepts the arguments _numberFormat_ (which must be an object), _locales_, and _options_. It initializes _numberFormat_ as a NumberFormat object. The following steps are taken:
+
+
+
+ 1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
+ 1. If _options_ is *undefined*, then
+ 1. Let _options_ be ObjectCreate(*null*).
+ 1. Else,
+ 1. Let _options_ be ? ToObject(_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 _localeData_ be %NumberFormat%.[[LocaleData]].
+ 1. Let _r_ be ResolveLocale(%NumberFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %NumberFormat%.[[RelevantExtensionKeys]], _localeData_).
+ 1. Set _numberFormat_.[[Locale]] to _r_.[[locale]].
+ 1. Set _numberFormat_.[[DataLocale]] to _r_.[[dataLocale]].
+ 1. Set _numberFormat_.[[NumberingSystem]] to _r_.[[nu]].
+ 1. Let _dataLocale_ be _r_.[[dataLocale]].
+ 1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, « `"decimal"`, `"percent"`, `"currency"` », `"decimal"`).
+ 1. Set _numberFormat_.[[Style]] to _style_.
+ 1. Let _currency_ be ? GetOption(_options_, `"currency"`, `"string"`, *undefined*, *undefined*).
+ 1. If _currency_ is not *undefined*, then
+ 1. If the result of IsWellFormedCurrencyCode(_currency_) is *false*, throw a *RangeError* exception.
+ 1. If _style_ is `"currency"` and _currency_ is *undefined*, throw a *TypeError* exception.
+ 1. If _style_ is `"currency"`, then
+ 1. Let _currency_ be the result of converting _currency_ to upper case as specified in .
+ 1. Set _numberFormat_.[[Currency]] to _currency_.
+ 1. Let _cDigits_ be CurrencyDigits(_currency_).
+ 1. Let _currencyDisplay_ be ? GetOption(_options_, `"currencyDisplay"`, `"string"`, « `"code"`, `"symbol"`, `"name"` », `"symbol"`).
+ 1. If _style_ is `"currency"`, set _numberFormat_.[[CurrencyDisplay]] to _currencyDisplay_.
+ 1. Perform ? SetNumberFormatUnitOptions(_numberFormat_, _options_).
+ 1. Let _style_ be _numberFormat_.[[Style]].
+ 1. If _style_ is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cDigits_ be CurrencyDigits(_currency_).
+ 1. Let _mnfdDefault_ be _cDigits_.
+ 1. Let _mxfdDefault_ be _cDigits_.
+ 1. Else,
+ 1. Let _mnfdDefault_ be 0.
+ 1. If _style_ is `"percent"`, then
+ 1. Let _mxfdDefault_ be 0.
+ 1. Else,
+ 1. Let _mxfdDefault_ be 3.
+ 1. Let _notation_ be ? GetOption(_options_, `"notation"`, `"string"`, « `"standard"`, `"scientific"`, `"engineering"`, `"compact"` », `"standard"`).
+ 1. Set _numberFormat_.[[Notation]] to _notation_.
+ 1. Perform ? SetNumberFormatDigitOptions(_numberFormat_, _options_, _mnfdDefault_, _mxfdDefault_).
+ 1. Let _compactDisplay_ be ? GetOption(_options_, `"compactDisplay"`, `"string"`, « `"short"`, `"long"` », `"short"`).
+ 1. If _notation_ is `"compact"`, then
+ 1. Set _numberFormat_.[[CompactDisplay]] to _compactDisplay_.
+ 1. Let _useGrouping_ be ? GetOption(_options_, `"useGrouping"`, `"boolean"`, *undefined*, *true*).
+ 1. Set _numberFormat_.[[UseGrouping]] to _useGrouping_.
+ 1. Let _signDisplay_ be ? GetOption(_options_, `"signDisplay"`, `"string"`, « `"auto"`, `"never"`, `"always"`, `"exceptZero"` », `"auto"`).
+ 1. Set _numberFormat_.[[SignDisplay]] to _signDisplay_.
+ 1. Let _dataLocaleData_ be _localeData_.[[<_dataLocale_>]].
+ 1. Let _patterns_ be _dataLocaleData_.[[patterns]].
+ 1. Assert: _patterns_ is a record (see ).
+ 1. Let _stylePatterns_ be _patterns_.[[<_style_>]].
+ 1. Set _numberFormat_.[[PositivePattern]] to _stylePatterns_.[[positivePattern]].
+ 1. Set _numberFormat_.[[NegativePattern]] to _stylePatterns_.[[negativePattern]].
+ 1. Return _numberFormat_.
+
+
+
+
+
CurrencyDigits ( _currency_ )
+
+
+ When the abstract operation CurrencyDigits is called with an argument _currency_ (which must be an upper case String value), the following steps are taken:
+
+
+
+ 1. If the ISO 4217 currency and funds code list contains _currency_ as an alphabetic code, return the minor unit value corresponding to the _currency_ from the list; otherwise, return 2.
+
+
+
+
+
Number Format Functions
+
+
A Number format function is an anonymous built-in function that has a [[NumberFormat]] internal slot.
+
When a Number format function _F_ is called with optional argument _value_, the following steps are taken:
+
+
+ 1. Let _nf_ be _F_.[[NumberFormat]].
+ 1. Assert: Type(_nf_) is Object and _nf_ has an [[InitializedNumberFormat]] internal slot.
+ 1. If _value_ is not provided, let _value_ be *undefined*.
+ 1. Let _x_ be ? ToNumber(_value_).
+ 1. Return FormatNumber(_nf_, _x_).
+
+
+
+ The `length` property of a Number format function is 1.
+
+
+
+
+
FormatNumberToString ( _intlObject_, _x_ )
+
+
+ The FormatNumberToString abstract operation is called with arguments _intlObject_ (which must be an object with [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], and [[MaximumFractionDigits]] internal slots), and _x_ (which must be a Number value), and returns a Record containing two values: _x_ as a string value with digits formatted according to the five formatting parameters in the field [[FormattedString]], and the final floating decimal value of _x_ after rounding has been performed in the field [[RoundedNumber]].
+
+
+
+
+ 1. If _intlObject_.[[MinimumSignificantDigits]] and _intlObject_.[[MaximumSignificantDigits]] are both not *undefined*, then
+ 1. Let _result_ be ToRawPrecision(_x_, _intlObject_.[[MinimumSignificantDigits]], _intlObject_.[[MaximumSignificantDigits]]).
+ 1. Else,
+ 1. Let _result_ be ToRawFixed(_x_, _intlObject_.[[MinimumIntegerDigits]], _intlObject_.[[MinimumFractionDigits]], _intlObject_.[[MaximumFractionDigits]]).
+ 1. Return _result_.
+
+
+
+
+ 1. Let _isNegative_ be _x_ < 0 or _x_ is *-0*.
+ 1. If _isNegative_, then
+ 1. Let _x_ be -_x_.
+ 1. If _intlObject_.[[RoundingType]] is `"significantDigits"`, then
+ 1. Let _result_ be ToRawPrecision(_x_, _intlObject_.[[MinimumSignificantDigits]], _intlObject_.[[MaximumSignificantDigits]]).
+ 1. Else If _intlObject_.[[RoundingType]] is `"fractionDigits"`, then,
+ 1. Let _result_ be ToRawFixed(_x_, _intlObject_.[[MinimumFractionDigits]], _intlObject_.[[MaximumFractionDigits]]).
+ 1. Else,
+ 1. Assert: _intlObject_.[[RoundingType]] is `"compactRounding"`.
+ 1. Let _result_ be ToRawFixed(_x_, 0, 0).
+ 1. If _result_.[[IntegerDigitsCount]] = 1, then
+ 1. Let _result_ be ToRawPrecision(_x_, 1, 2).
+ 1. Let _x_ be _result_.[[RoundedNumber]].
+ 1. Let _string_ be _result_.[[FormattedString]].
+ 1. Let _int_ be _result_.[[IntegerDigitsCount]].
+ 1. Let _minInteger_ be _intlObject_.[[MinimumIntegerDigits]].
+ 1. If _int_ < _minInteger_, then
+ 1. Let _forwardZeros_ be the String consisting of _minInteger_–_int_ occurrences of the character `"0"`.
+ 1. Let _string_ be the concatenation of Strings _forwardZeros_ and _string_.
+ 1. If _isNegative_, then
+ 1. Let _x_ be -_x_.
+ 1. Return the Record { [[RoundedNumber]]: _x_, [[FormattedString]]: _string_ }.
+
+
+
+
+
+
PartitionNumberPattern ( _numberFormat_, _x_ )
+
+
+ The PartitionNumberPattern abstract operation is called with arguments _numberFormat_ (which must be an object initialized as a NumberFormat) and _x_ (which must be a Number value), interprets _x_ as a numeric value, and creates the corresponding parts according to the effective locale and the formatting options of _numberFormat_. The following steps are taken:
+
+
+
+ 1. If _x_ is not *NaN* and _x_ < 0 or _x_ is *-0*, then
+ 1. Let _x_ be -_x_.
+ 1. Let _pattern_ be _numberFormat_.[[NegativePattern]].
+ 1. Else,
+ 1. Let _pattern_ be _numberFormat_.[[PositivePattern]].
+ 1. Let _exponent_ be 0.
+ 1. If _x_ is *NaN*, then
+ 1. Let _n_ be an implementation- and locale-dependent (ILD) String value indicating the *NaN* value.
+ 1. Else if _x_ is not a finite Number,
+ 1. Let _n_ be an ILD String value indicating infinity.
+ 1. Else,
+ 1. If _numberFormat_.[[Style]] is `"percent"`, let _x_ be 100 × _x_.
+ 1. Let _exponent_ be ComputeExponent(_numberFormat_, _x_).
+ 1. Let _x_ be _x_ × 10-_exponent_.
+ 1. Let _formatNumberResult_ be FormatNumberToString(_numberFormat_, _x_).
+ 1. Let _n_ be _formatNumberResult_.[[FormattedString]].
+ 1. Let _x_ be _formatNumberResult_.[[RoundedNumber]].
+ 1. Let _pattern_ be GetNumberFormatPattern(_numberFormat_, _x_, _exponent_)
+ 1. Let _result_ be a new empty List.
+ 1. Let _beginIndex_ be Call(%StringProto_indexOf%, _pattern_, « `"{"`, 0 »).
+ 1. Let _endIndex_ be 0.
+ 1. Let _nextIndex_ be 0.
+ 1. Let _length_ be the number of code units in _pattern_.
+ 1. Repeat, while _beginIndex_ is an integer index into _pattern_
+ 1. Set _endIndex_ to Call(%StringProto_indexOf%, _pattern_, « `"}"`, _beginIndex_ »).
+ 1. Assert: _endIndex_ is greater than _beginIndex_.
+ 1. If _beginIndex_ is greater than _nextIndex_, then
+ 1. Let _literal_ be a substring of _pattern_ from position _nextIndex_, inclusive, to position _beginIndex_, exclusive.
+ 1. Append a new Record { [[Type]]: `"literal"`, [[Value]]: _literal_ } as the last element of _result_.
+ 1. Let _p_ be the substring of _pattern_ from position _beginIndex_, exclusive, to position _endIndex_, exclusive.
+ 1. If _p_ is equal to `"number"`, then
+ 1. If _x_ is *NaN*, then
+ 1. Let _n_ be an implementation- and locale-dependent (ILD) String value indicating the *NaN* value.
+ 1. Append a new Record { [[Type]]: `"nan"`, [[Value]]: _n_ } as the last element of _result_.
+ 1. Else if _x_ is not a finite Number,
+ 1. Let _n_ be an ILD String value indicating infinity.
+ 1. Append a new Record { [[Type]]: `"infinity"`, [[Value]]: _n_ } as the last element of _result_.
+ 1. Else,
+ 1. If _numberFormat_.[[Style]] is `"percent"`, let _x_ be 100 × _x_.
+ 1. Let _n_ be FormatNumberToString(_numberFormat_, _x_).
+ 1. If the _numberFormat_.[[NumberingSystem]] matches one of the values in the `"Numbering System"` column of below, then
+ 1. Let _digits_ be a List whose 10 String valued elements are the UTF-16 string representations of the 10 _digits_ specified in the `"Digits"` column of the matching row in .
+ 1. Replace each _digit_ in _n_ with the value of _digits_[_digit_].
+ 1. Else use an implementation dependent algorithm to map _n_ to the appropriate representation of _n_ in the given numbering system.
+ 1. Let _decimalSepIndex_ be Call(%StringProto_indexOf%, _n_, « `"."`, 0 »).
+ 1. If _decimalSepIndex_ > 0, then
+ 1. Let _integer_ be the substring of _n_ from position 0, inclusive, to position _decimalSepIndex_, exclusive.
+ 1. Let _fraction_ be the substring of _n_ from position _decimalSepIndex_, exclusive, to the end of _n_.
+ 1. Else,
+ 1. Let _integer_ be _n_.
+ 1. Let _fraction_ be *undefined*.
+ 1. If the _numberFormat_.[[UseGrouping]] is *true*, then
+ 1. Let _groupSepSymbol_ be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
+ 1. Let _groups_ be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the _integer_.
+ 1. Assert: The number of elements in _groups_ List is greater than 0.
+ 1. Repeat, while _groups_ List is not empty
+ 1. Remove the first element from _groups_ and let _integerGroup_ be the value of that element.
+ 1. Append a new Record { [[Type]]: `"integer"`, [[Value]]: _integerGroup_ } as the last element of _result_.
+ 1. If _groups_ List is not empty, then
+ 1. Append a new Record { [[Type]]: `"group"`, [[Value]]: _groupSepSymbol_ } as the last element of _result_.
+ 1. Else,
+ 1. Append a new Record { [[Type]]: `"integer"`, [[Value]]: _integer_ } as the last element of _result_.
+ 1. If _fraction_ is not *undefined*, then
+ 1. Let _decimalSepSymbol_ be the ILND String representing the decimal separator.
+ 1. Append a new Record { [[Type]]: `"decimal"`, [[Value]]: _decimalSepSymbol_ } as the last element of _result_.
+ 1. Append a new Record { [[Type]]: `"fraction"`, [[Value]]: _fraction_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"plusSign"`, then
+ 1. Let _plusSignSymbol_ be the ILND String representing the plus sign.
+ 1. Append a new Record { [[Type]]: `"plusSign"`, [[Value]]: _plusSignSymbol_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"minusSign"`, then
+ 1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
+ 1. Append a new Record { [[Type]]: `"minusSign"`, [[Value]]: _minusSignSymbol_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"compactSymbol"`, then
+ 1. Let _compactSymbol_ be an ILD string representing _exponent_ in short form, which may depend on _x_ in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a `"{compactSymbol}"` placeholder.
+ 1. Append a new Record { [[Type]]: `"compact"`, [[Value]]: _compactSymbol_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"compactName"`, then
+ 1. Let _compactName_ be an ILD string representing _exponent_ in long form, which may depend on _x_ in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a `"{compactName}"` placeholder.
+ 1. Append a new Record { [[Type]]: `"compact"`, [[Value]]: _compactName_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"scientificSeparator"`, then
+ 1. Let _scientificSeparator_ be the ILND String representing the exponent separator.
+ 1. Append a new Record { [[Type]]: `"exponentSeparator"`, [[Value]]: _scientificSeparator_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"scientificExponent"`, then
+ 1. If _exponent_ < 0, then
+ 1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
+ 1. Append a new Record { [[Type]]: `"exponentMinusSign"`, [[Value]]: _minusSignSymbol_ } as the last element of _result_.
+ 1. Let _exponent_ be -_exponent_.
+ 1. Let _exponentResult_ be ToRawFixed(_exponent_, 1, 0, 0).
+ 1. Append a new Record { [[Type]]: `"exponentInteger"`, [[Value]]: _exponentResult_.[[FormattedString]] } as the last element of _result_.
+ 1. Else if _p_ is equal to `"percentSign"` and _numberFormat_.[[Style]] is `"percent"`, then
+ 1. Let _percentSignSymbol_ be the ILND String representing the percent sign.
+ 1. Append a new Record { [[Type]]: `"percentSign"`, [[Value]]: _percentSignSymbol_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"unitSymbol"` and _numberFormat_.[[Style]] is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _mu_ be an ILD string representing _unit_ in short form, which may depend on _x_ in languages having different plural forms.
+ 1. Append a new Record { [[Type]]: `"unit"`, [[Value]]: _mu_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"unitNarrowSymbol"` and _numberFormat_.[[Style]] is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _mu_ be an ILD string representing _unit_ in narrow form, which may depend on _x_ in languages having different plural forms.
+ 1. Append a new Record { [[Type]]: `"unit"`, [[Value]]: _mu_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"unitName"` and _numberFormat_.[[Style]] is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _mu_ be an ILD string representing _unit_ in long form, which may depend on _x_ in languages having different plural forms.
+ 1. Append a new Record { [[Type]]: `"unit"`, [[Value]]: _mu_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currency"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Assert: _numberFormat_.[[CurrencyDisplay]] is `"code"`, `"symbol"` or `"name"`.
+ 1. If _numberFormat_.[[CurrencyDisplay]] is `"code"`, then
+ 1. Let _cd_ be _currency_.
+ 1. Else if _numberFormat_.[[CurrencyDisplay]] is `"symbol"`, then
+ 1. Let _cd_ be an ILD string representing _currency_ in short form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Else if _numberFormat_.[[CurrencyDisplay]] is `"name"`, then
+ 1. Let _cd_ be an ILD string representing _currency_ in long form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencyCode"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be _currency_.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencySymbol"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be an ILD string representing _currency_ in short form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencyNarrowSymbol"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be an ILD string representing _currency_ in narrow form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencyName"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be an ILD string representing _currency_ in long form, which may depend on _x_ in languages having different plural forms. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else,
+ 1. Let _unknown_ be an ILND String based on _x_ and _p_.
+ 1. Append a new Record { [[Type]]: `"unknown"`, [[Value]]: _unknown_ } as the last element of _result_.
+ 1. Set _nextIndex_ to _endIndex_ + 1.
+ 1. Set _beginIndex_ to Call(%StringProto_indexOf%, _pattern_, « `"{"`, _nextIndex_ »).
+ 1. If _nextIndex_ is less than _length_, then
+ 1. Let _literal_ be the substring of _pattern_ from position _nextIndex_, inclusive, to position _length_, exclusive.
+ 1. Append a new Record { [[Type]]: `"literal"`, [[Value]]: _literal_ } as the last element of _result_.
+ 1. Return _result_.
+
+
+
+ Numbering systems with simple digit mappings
+
+
+
+
+ The computations rely on String values and locations within numeric strings that are dependent upon the implementation and the effective locale of _numberFormat_ ("ILD") or upon the implementation, the effective locale, and the numbering system of _numberFormat_ ("ILND"). The ILD and ILND Strings mentioned, other than those for currency names, must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
+
+
+ It is recommended that implementations use the locale provided by the Common Locale Data Repository (available at http://cldr.unicode.org/).
+
+
+
+
+
FormatNumber( _numberFormat_, _x_ )
+
+
+ The FormatNumber abstract operation is called with arguments _numberFormat_ (which must be an object initialized as a NumberFormat) and _x_ (which must be a Number value), and performs the following steps:
+
+
+
+ 1. Let _parts_ be ? PartitionNumberPattern(_numberFormat_, _x_).
+ 1. Let _result_ be the 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_.
+
+
+
+
+
FormatNumberToParts( _numberFormat_, _x_ )
+
+
+ The FormatNumberToParts abstract operation is called with arguments _numberFormat_ (which must be an object initialized as a NumberFormat) and _x_ (which must be a Number value), and performs the following steps:
+
+
+
+ 1. Let _parts_ be ? PartitionNumberPattern(_numberFormat_, _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. 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_.
+
+
+
+
+
+ When the ToRawPrecision abstract operation is called with arguments _x_ (which must be a finite non-negative number), _minPrecision_, and _maxPrecision_ (both must be integers between 1 and 21), the following steps are taken:
+
+
+
+ 1. Let _p_ be _maxPrecision_.
+ 1. If _x_ = 0, then
+ 1. Let _m_ be the String consisting of _p_ occurrences of the character `"0"`.
+ 1. Let _e_ be 0.
+ 1. Let _xFinal_ be 0.
+ 1. Else,
+ 1. Let _e_ and _n_ be integers such that 10_p_–1 ≤ _n_ < 10_p_ and for which the exact mathematical value of _n_ × 10_e_–_p_+1 – _x_ is as close to zero as possible. If there are two such sets of _e_ and _n_, pick the _e_ and _n_ for which _n_ × 10_e_–_p_+1 is larger.
+ 1. Let _e_ be the base 10 logarithm of _x_ rounded down to the nearest integer.
+ 1. Let _n_ be an integer such that 10_p_–1 ≤ _n_ < 10_p_ and for which the exact mathematical value of _n_ × 10_e_–_p_+1 – _x_ is as close to zero as possible. If there is more than one such _n_, pick the one for which _n_ × 10_e_–_p_+1 is larger.
+ 1. Let _m_ be the String consisting of the digits of the decimal representation of _n_ (in order, with no leading zeroes).
+ 1. Let _xFinal_ be _n_ × 10_e_–_p_+1.
+ 1. If _e_ ≥ _p_, then
+ 1. Return the concatenation of _m_ and _e_-_p_+1 occurrences of the character `"0"`.
+ 1. If _e_ = _p_-1, then
+ 1. Return _m_.
+ 1. If _e_ ≥ _p_–1, then
+ 1. Let _m_ be the concatenation of _m_ and _e_–_p_+1 occurrences of the character `"0"`.
+ 1. Let _int_ be _e_+1.
+ 1. Else If _e_ ≥ 0, then
+ 1. Let _m_ be the concatenation of the first _e_+1 characters of _m_, the character `"."`, and the remaining _p_–(_e_+1) characters of _m_.
+ 1. Let _int_ be _e_+1.
+ 1. If _e_ < 0, thenElse,
+ 1. Assert: _e_ < 0.
+ 1. Let _m_ be the concatenation of the String `"0."`, –(_e_+1) occurrences of the character `"0"`, and the string _m_.
+ 1. Let _int_ be 1.
+ 1. If _m_ contains the character `"."`, and _maxPrecision_ > _minPrecision_, then
+ 1. Let _cut_ be _maxPrecision_ – _minPrecision_.
+ 1. Repeat, while _cut_ > 0 and the last character of _m_ is `"0"`
+ 1. Remove the last character from _m_.
+ 1. Decrease _cut_ by 1.
+ 1. If the last character of _m_ is `"."`, then
+ 1. Remove the last character from _m_.
+ 1. Return _m_.
+ 1. Return the Record { [[FormattedString]]: _m_, [[RoundedNumber]]: _xFinal_, [[IntegerDigitsCount]]: _int_ }.
+
+
+
+
+
+ When the ToRawFixed abstract operation is called with arguments _x_ (which must be a finite non-negative number), _minInteger_ (which must be an integer between 1 and 21), _minFraction_, and _maxFraction_ (which must be integers between 0 and 20), the following steps are taken:
+
+
+
+ 1. Let _f_ be _maxFraction_.
+ 1. Let _n_ be an integer for which the exact mathematical value of _n_ ÷ 10_f_ – _x_ is as close to zero as possible. If there are two such _n_, pick the larger _n_.
+ 1. Let _xFinal_ be _n_ ÷ 10_f_.
+ 1. If _n_ = 0, let _m_ be the String `"0"`. Otherwise, let _m_ be the String consisting of the digits of the decimal representation of _n_ (in order, with no leading zeroes).
+ 1. If _f_ ≠ 0, then
+ 1. Let _k_ be the number of characters in _m_.
+ 1. If _k_ ≤ _f_, then
+ 1. Let _z_ be the String consisting of _f_+1–_k_ occurrences of the character `"0"`.
+ 1. Let _m_ be the concatenation of Strings _z_ and _m_.
+ 1. Let _k_ be _f_+1.
+ 1. Let _a_ be the first _k_–_f_ characters of _m_, and let _b_ be the remaining _f_ characters of _m_.
+ 1. Let _m_ be the concatenation of the three Strings _a_, `"."`, and _b_.
+ 1. Let _int_ be the number of characters in _a_.
+ 1. Else, let _int_ be the number of characters in _m_.
+ 1. Let _cut_ be _maxFraction_ – _minFraction_.
+ 1. Repeat, while _cut_ > 0 and the last character of _m_ is `"0"`
+ 1. Remove the last character from _m_.
+ 1. Decrease _cut_ by 1.
+ 1. If the last character of _m_ is `"."`, then
+ 1. Remove the last character from _m_.
+ 1. If _int_ < _minInteger_, then
+ 1. Let _z_ be the String consisting of _minInteger_–_int_ occurrences of the character `"0"`.
+ 1. Let _m_ be the concatenation of Strings _z_ and _m_.
+ 1. Return _m_.
+ 1. Return the Record { [[FormattedString]]: _m_, [[RoundedNumber]]: _xFinal_, [[IntegerDigitsCount]]: _int_ }.
+
+
+
+
+
UnwrapNumberFormat( _nf_ )
+
+ The UnwrapNumberFormat abstract operation gets the underlying NumberFormat operation
+ for various methods which implement ECMA-402 v1 semantics for supporting initializing
+ existing Intl objects.
+
+
+ 1. Assert: Type(_nf_) is Object.
+
+
+
+ 2. If _nf_ does not have an [[InitializedNumberFormat]] internal slot and ? InstanceofOperator(_nf_, %NumberFormat%) is *true*, then
+ 1. Let _nf_ be ? Get(_nf_, %Intl%.[[FallbackSymbol]]).
+
+
+
+ 3. If Type(_nf_) is not Object or _nf_ does not have an [[InitializedNumberFormat]] internal slot, then
+ 1. Throw a *TypeError* exception.
+ 1. Return _nf_.
+
+ See for the motivation of the normative optional text.
+
+
+
+
+
+ The abstract operation SetNumberFormatUnitOptions resolves the user-specified options relating to units onto the intl object.
+
+
+ 1. Assert: Type(_intlObj_) is Object.
+ 1. Assert: Type(_options_) is Object.
+ 1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, « `"decimal"`, `"percent"`, `"currency"`, `"unit"` », `"decimal"`).
+ 1. Set _intlObj_.[[Style]] to _style_.
+ 1. Let _currency_ be ? GetOption(_options_, `"currency"`, `"string"`, *undefined*, *undefined*).
+ 1. Let _currencyDisplay_ be ? GetOption(_options_, `"currencyDisplay"`, `"string"`, « `"code"`, `"symbol"`, `"narrowSymbol"`, `"name"` », `"symbol"`).
+ 1. Let _currencySign_ be ? GetOption(_options_, `"currencySign"`, `"string"`, « `"standard"`, `"accounting"` », `"standard"`).
+ 1. Let _unit_ be ? GetOption(_options_, `"unit"`, `"string"`, *undefined*, *undefined*).
+ 1. Let _unitDisplay_ be ? GetOption(_options_, `"unitDisplay"`, `"string"`, « `"short"`, `"narrow"`, `"long"` », `"short"`).
+ 1. If _style_ is `"currency"`, then
+ 1. If _currency_ is *undefined*, throw a *TypeError* exception.
+ 1. If the result of IsWellFormedCurrencyCode(_currency_) is *false*, throw a *RangeError* exception.
+ 1. Let _currency_ be the result of converting _currency_ to upper case as specified in .
+ 1. Set _intlObj_.[[Currency]] to _currency_.
+ 1. Set _intlObj_.[[CurrencyDisplay]] to _currencyDisplay_.
+ 1. Set _intlObj_.[[CurrencySign]] to _currencySign_.
+ 1. If _style_ is `"unit"`, then
+ 1. If _unit_ is *undefined*, throw a *TypeError* exception.
+ 1. If the result of IsWellFormedUnitIdentifier(_unit_) is *false*, throw a *RangeError* exception.
+ 1. Set _intlObj_.[[Unit]] to _unit_.
+ 1. Set _intlObj_.[[UnitDisplay]] to _unitDisplay_.
+
+
+
+
+
+
+
+ The abstract operation GetNumberFormatPattern considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted and returns a pattern, a String value as described in .
+
+
+ 1. Let _localeData_ be %NumberFormat%.[[LocaleData]].
+ 1. Let _dataLocale_ be _numberFormat_.[[DataLocale]].
+ 1. Let _dataLocaleData_ be _localeData_.[[<_dataLocale_>]].
+ 1. Let _patterns_ be _dataLocaleData_.[[patterns]].
+ 1. Assert: _patterns_ is a Record (see ).
+ 1. Let _style_ be _numberFormat_.[[Style]].
+ 1. If _style_ is `"percent"`, then
+ 1. Let _patterns_ be _patterns_.[[`"percent"`]].
+ 1. Else If _style_ is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _unitDisplay_ be _numberFormat_.[[UnitDisplay]].
+ 1. Let _patterns_ be _patterns_.[[`"unit"`]].
+ 1. If _patterns_.[[<_unit_>]] is *undefined*, then
+ 1. Let _unit_ be `"fallback"`.
+ 1. Let _patterns_ be _patterns_.[[<_unit_>]].
+ 1. Let _patterns_ be _patterns_.[[<_unitDisplay_>]].
+ 1. Else If _style_ is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _currencyDisplay_ be _numberFormat_.[[CurrencyDisplay]].
+ 1. Let _currencySign_ be _numberFormat_.[[CurrencySign]].
+ 1. Let _patterns_ be _patterns_.[[`"currency"`]].
+ 1. If _patterns_.[[<_currency_>]] is *undefined*, then
+ 1. Let _currency_ be `"fallback"`.
+ 1. Let _patterns_ be _patterns_.[[<_currency_>]].
+ 1. Let _patterns_ be _patterns_.[[<_currencyDisplay_>]].
+ 1. Let _patterns_ be _patterns_.[[<_currencySign_>]].
+ 1. Else,
+ 1. Assert: _style_ is `"decimal"`.
+ 1. Let _patterns_ be _patterns_.[[`"decimal"`]].
+ 1. Let _signDisplay_ be _numberFormat_.[[SignDisplay]].
+ 1. Let _patterns_ be _patterns_.[[<_signDisplay_>]].
+ 1. Let _notation_ be _numberFormat_.[[Notation]].
+ 1. Let _displayNotation_ be `"standard"`.
+ 1. If _notation_ is `"scientific"` or _notation_ is `"engineering"`, then
+ 1. Let _displayNotation_ be `"scientific"`.
+ 1. Else If _exponent_ is not 0, then
+ 1. Assert: _notation_ is `"compact"`.
+ 1. Let _compactDisplay_ be _numberFormat_.[[CompactDisplay]].
+ 1. If _compactDisplay_ is `"short"`, then
+ 1. Let _displayNotation_ be `"compactShort"`.
+ 1. Else,
+ 1. Assert: _compactDisplay_ is `"long"`.
+ 1. Let _displayNotation_ be `"compactLong"`.
+ 1. Let _patterns_ be _patterns_.[[<_displayNotation_>]].
+ 1. If _x_ is not *NaN* and _x_ < 0 or _x_ is *-0*, then
+ 1. Let _pattern_ be _patterns_.[[negativePattern]].
+ 1. Else If _x_ is 0, then
+ 1. Let _pattern_ be _patterns_.[[zeroPattern]].
+ 1. Else,
+ 1. Let _pattern_ be _patterns_.[[positivePattern]].
+ 1. Return _pattern_.
+
+
+
+
+
+
+
ComputeExponent ( _numberFormat_, _x_ )
+
+ The abstract operation ComputeExponent computes an exponent (power of ten) by which to scale _x_ according to the number formatting settings. It handles cases such as 999 rounding up to 1000, requiring a different exponent.
+
+
+ 1. If _x_ = 0, then
+ 1. Return 0.
+ 1. If _x_ < 0, then
+ 1. Let _x_ = -_x_.
+ 1. Let _magnitude_ be the base 10 logarithm of _x_ rounded down to the nearest integer.
+ 1. Let _exponent_ be ComputeExponentForMagnitude(_numberFormat_, _magnitude_).
+ 1. Let _x_ be _x_ × 10-_exponent_.
+ 1. Let _formatNumberResult_ be FormatNumberToString(_numberFormat_, _x_).
+ 1. If _formatNumberResult_.[[RoundedNumber]] = 0, then
+ 1. Return _exponent_.
+ 1. Let _newMagnitude_ be the base 10 logarithm of _x_ rounded down to the nearest integer.
+ 1. If _newMagnitude_ is _magnitude_ – _exponent_, then
+ 1. Return _exponent_.
+ 1. Return ComputeExponentForMagnitude(_numberFormat_, _magnitude_ + 1).
+
+
+
+
+
+
+
+ The abstract operation ComputeExponentHelper computes an exponent by which to scale a number of the given magnitude (power of ten of the most significant digit) according to the locale and the desired notation (scientific, engineering, or compact).
+
+
+ 1. Let _notation_ be _numberFormat_.[[Notation]].
+ 1. If _notation_ is `"standard"`, then
+ 1. Return 0.
+ 1. Else If _notation_ is `"scientific"`, then
+ 1. Return _magnitude_.
+ 1. Else If _notation_ is `"engineering"`, then
+ 1. Let _thousands_ be the greatest integer that is not greater than _magnitude_ ÷ 3.
+ 1. Return _thousands_ × 3.
+ 1. Else,
+ 1. Assert: _notation_ is `"compact"`.
+ 1. Let _exponent_ be an implementation-dependent integer by which to scale a number of the given magnitude in compact notation for the current locale.
+ 1. Return _exponent_.
+
+
+
+
+
+
+
The Intl.NumberFormat Constructor
+
+
+ The NumberFormat constructor is the %NumberFormat% intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in .
+
+ When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:
+
+
+
+ 1. Let _availableLocales_ be %NumberFormat%.[[AvailableLocales]].
+ 1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
+ 1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).
+
+
+
+ The value of the `length` property of the *supportedLocalesOf* method is 1.
+
+
+
+
+
Internal slots
+
+
+ The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in .
+
+
+
+ The value of the [[RelevantExtensionKeys]] internal slot is « `"nu"` ».
+
+
+
+ Unicode Technical Standard 35 describes two locale extension keys that are relevant to number formatting, `"nu"` for numbering system and `"cu"` for currency. Intl.NumberFormat, however, requires that the currency of a currency format is specified through the currency property in the options objects.
+
+
+
+ The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in and the following additional constraints:
+
+
+
+
The list that is the value of the `"nu"` field of any locale field of [[LocaleData]] must not include the values `"native"`, `"traditio"`, or `"finance"`.
+
[[LocaleData]][locale] must have a patterns field for all locale values. The value of this field must be a recordRecord, which must have fields with the names of the threefour number format styles: `"decimal"`, `"percent"`, `"currency"`, and `"unit"`. Each of these fields in turn must be a record with the fields positivePattern and negativePattern.
+
The two fields `"currency"` and `"unit"` noted above must be Records with at least one field, `"fallback"`. The `"currency"` may have additional fields with keys corresponding to currency codes according to . Each field of `"currency"` must be a Record with fields corresponding to the possible currencyDisplay values: `"code"`, `"symbol"`, `"narrowSymbol"`, and `"name"`. Each of those fields must contain a Record with fields corresponding to the possible currencySign values: `"standard"` or `"accounting"`. The `"unit"` field (of [[LocaleData]][locale]) may have additional fields beyond the required field `"fallback"` with keys corresponding to measurement core unit identifiers corresponding to . Each field of `"unit"` must be a Record with fields corresponding to the possible unitDisplay values: `"narrow"`, `"short"`, and `"long"`.
+
All of the leaf fields so far described for the patterns tree (`"decimal"`, `"percent"`, great-grandchildren of `"currency"`, and grandchildren of `"unit"`) must be Records with fields corresponding to the possible signDisplay values: `"auto"`, `"always"`, `"never"`, and `"exceptZero"`. Each of these fields must be a Record with the keys `"standard"`, `"scientific"`, `"compactShort"`, and `"compactLong"`. Each of these fields must be a Record with the keys `"positivePattern"`, `"zeroPattern"`, and `"negativePattern"`.
+
The value of these fields the aforementioned fields (the sign-dependent pattern fields) must be string values that must contain the substring `"{number}"` and may contain the substrings `"{plusSign}"`, and `"{minusSign}"`, `"{compactSymbol}"`, `"{compactName}"`, `"{scientificSeparator}"`, and `"{scientificExponent}"`; the values within the percent`"percent"` field must also contain the substring `"{percentSign}"`; the values within the currency`"currency"` field must also contain the substring `"{currency}"` one of the following substrings: `"{currencyCode}"`, `"{currencySymbol}"`, `"{currencyNarrowSymbol}"`, or `"{currencyName}"`; and the values within the `"unit"` field must also contain one of the following substrings: `"{unitSymbol}"`, `"{unitNarrowSymbol}"`, or `"{unitName}"`. The pattern strings must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
+
+
+ It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at http://cldr.unicode.org/).
+
+
+
+
+
+
Properties of the Intl.NumberFormat Prototype Object
+
+
+ The Intl.NumberFormat prototype object is itself an ordinary object. %NumberFormatPrototype% is not an Intl.NumberFormat instance and does not have an [[InitializedNumberFormat]] internal slot or any of the other internal slots of Intl.NumberFormat instance objects.
+
+
+
+
Intl.NumberFormat.prototype.constructor
+
+
+ The initial value of `Intl.NumberFormat.prototype.constructor` is the intrinsic object %NumberFormat%.
+
+
+
+
+
Intl.NumberFormat.prototype [ @@toStringTag ]
+
+
+ The initial value of the @@toStringTag property is the string value `"Object"`.
+
+
+ This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
+
+
+
+
+
get Intl.NumberFormat.prototype.format
+
+
+ Intl.NumberFormat.prototype.format is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:
+
+
+
+ 1. Let _nf_ be the *this* value.
+ 1. If Type(_nf_) is not Object, throw a *TypeError* exception.
+ 1. Let _nf_ be ? UnwrapNumberFormat(_nf_).
+ 1. If _nf_.[[BoundFormat]] is *undefined*, then
+ 1. Let _F_ be a new built-in function object as defined in Number Format Functions ().
+ 1. Set _F_.[[NumberFormat]] to _nf_.
+ 1. Set _nf_.[[BoundFormat]] to _F_.
+ 1. Return _nf_.[[BoundFormat]].
+
+
+
+ The returned function is bound to _nf_ so that it can be passed directly to `Array.prototype.map` or other functions.
+ This is considered a historical artefact, as part of a convention which is no longer followed for new features, but is preserved to maintain compatibility with existing programs.
+
+
+
+
+
+ When the `formatToParts` method is called with an optional argument _value_, the following steps are taken:
+
+
+
+ 1. Let _nf_ be the *this* value.
+ 1. If Type(_nf_) is not Object, throw a *TypeError* exception.
+ 1. If _nf_ does not have an [[InitializedNumberFormat]] internal slot, throw a *TypeError* exception.
+ 1. Let _x_ be ? ToNumber(_value_).
+ 1. Return ? FormatNumberToParts(_nf_, _x_).
+
+
+
+
+
Intl.NumberFormat.prototype.resolvedOptions ()
+
+
+ This function provides access to the locale and formatting options computed during initialization of the object.
+
+
+
+ 1. Let _nf_ be *this* value.
+ 1. If Type(_nf_) is not Object, throw a *TypeError* exception.
+ 1. Let _nf_ be ? UnwrapNumberFormat(_nf_).
+ 1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).
+ 1. For each row of , except the header row, in table order, do
+ 1. Let _p_ be the Property value of the current row.
+ 1. Let _v_ be the value of _nf_'s internal slot whose name is the Internal Slot value of the current row.
+ 1. If _v_ is not *undefined*, then
+ 1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_).
+ 1. Return _options_.
+
+
+
+ Resolved Options of NumberFormat Instances
+
+
+
+
Internal Slot
+
Property
+
+
+
+
[[Locale]]
+
`"locale"`
+
+
+
[[NumberingSystem]]
+
`"numberingSystem"`
+
+
+
[[Style]]
+
`"style"`
+
+
+
[[Currency]]
+
`"currency"`
+
+
+
[[CurrencyDisplay]]
+
`"currencyDisplay"`
+
+
+
[[CurrencySign]]
+
`"currencySign"`
+
+
+
[[Unit]]
+
`"unit"`
+
+
+
[[UnitDisplay]]
+
`"unitDisplay"`
+
+
+
[[MinimumIntegerDigits]]
+
`"minimumIntegerDigits"`
+
+
+
[[MinimumFractionDigits]]
+
`"minimumFractionDigits"`
+
+
+
[[MaximumFractionDigits]]
+
`"maximumFractionDigits"`
+
+
+
[[MinimumSignificantDigits]]
+
`"minimumSignificantDigits"`
+
+
+
[[MaximumSignificantDigits]]
+
`"maximumSignificantDigits"`
+
+
+
[[UseGrouping]]
+
`"useGrouping"`
+
+
+
[[Notation]]
+
`"notation"`
+
+
+
[[CompactDisplay]]
+
`"compactDisplay"`
+
+
+
[[SignDisplay]]
+
`"signDisplay"`
+
+
+
+
+
+
+
+
Properties of Intl.NumberFormat Instances
+
+
+ Intl.NumberFormat instances inherit properties from %NumberFormatPrototype%.
+
+
+
+ Intl.NumberFormat instances have an [[InitializedNumberFormat]] internal slot.
+
+
+
+ Intl.NumberFormat instances also have several internal slots that are computed by the constructor:
+
+
+
+
[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.
+
[[DataLocale]] is a String value with the language tag of the nearest locale for which the implementation has data to perform the formatting operation. It will be a parent locale of [[Locale]].
+
[[NumberingSystem]] is a String value with the "type" given in Unicode Technical Standard 35 for the numbering system used for formatting.
+
[[Style]] is one of the String values `"decimal"`, `"currency"`, or `"percent"`, or `"unit"`, identifying the number format style usedthe type of quantity being measured.
+
[[Currency]] is a String value with the currency code identifying the currency to be used if formatting with the `"currency"` styleunit type. It is only used when [[Style]] has the value `"currency"`.
+
[[CurrencyDisplay]] is one of the String values `"code"`, `"symbol"`, `"narrowSymbol"`, or `"name"`, specifying whether to display the currency as an ISO 4217 alphabetic currency code, a localized currency symbol, or a localized currency name if formatting with the `"currency"` style. It is only used when [[Style]] has the value `"currency"`.
+
[[CurrencySign]] is one of the String values `"standard"` or `"accounting"`, specifying whether to render negative numbers in accounting format, often signified by parenthesis. It is only used when [[Style]] has the value `"currency"` and when [[SignDisplay]] is not `"never"`.
+
[[Unit]] is a core unit identifier, as defined by Unicode Technical Standard #35, Part 2, Section 6. It is only used when [[Style]] has the value `"unit"`.
+
[[UnitDisplay]] is one of the String values `"short"`, `"narrow"`, or `"long"`, specifying whether to display the unit as a symbol, narrow symbol, or localized long name if formatting with the `"unit"` style. It is only used when [[Style]] has the value `"unit"`.
+
[[MinimumIntegerDigits]] is a non-negative integer Number value indicating the minimum integer digits to be used. Numbers will be padded with leading zeroes if necessary.
+
[[MinimumFractionDigits]] and [[MaximumFractionDigits]] are non-negative integer Number values indicating the minimum and maximum fraction digits to be used. Numbers will be rounded or padded with trailing zeroes if necessary. These properties are only used when [[RoundingType]] is `"fractionDigits"`.
+
[[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] are positive integer Number values indicating the minimum and maximum fraction digits to be shown. Either none or both of these properties are present; if they are, they override minimum and maximum integer and fraction digits – If present, the formatter uses however many integer and fraction digits are required to display the specified number of significant digits. These properties are only used when [[RoundingType]] is `"significantDigits"`.
+
[[UseGrouping]] is a Boolean value indicating whether a grouping separator should be used.
+
[[RoundingType]] is one of the String values `"fractionDigits"`, `"significantDigits"`, or `"compactRounding"`, indicating which rounding strategy to use. If `"fractionDigits"`, the number is rounded according to [[MinimumFractionDigits]] and [[MaximumFractionDigits]], as described above. If `"significantDigits"`, the number is rounded according to [[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] as described above. If `"compactRounding"`, the number is rounded to 1 maximum fraction digit if there is 1 digit before the decimal separator, and otherwise round to 0 fraction digits.
+
[[Notation]] is one of the String values `"standard"`, `"scientific"`, `"engineering"`, or `"compact"`, specifying whether the number should be displayed without scaling, scaled to the units place with the power of ten in scientific notation, scaled to the nearest thousand with the power of ten in scientific notation, or scaled to the nearest locale-dependent compact decimal notation power of ten with the corresponding compact decimal notation affix.
+
[[CompactDisplay]] is one of the String values `"short"` or `"long"`, specifying whether to display compact notation affixes in short form ("5K") or long form ("5 thousand") if formatting with the `"compact"` notation. It is only used when [[Notation]] has the value `"compact"`.
+
[[SignDisplay]] is one of the String values `"auto"`, `"always"`, `"never"`, or `"exceptZero"`, specifying whether to show the sign on negative numbers only, positive and negative numbers including zero, neither positive nor negative numbers, or positive and negative numbers but not zero.
+
[[PositivePattern]] and [[NegativePattern]] are String values as described in .
+
+
+
+ Finally, Intl.NumberFormat instances have a [[BoundFormat]] internal slot that caches the function returned by the format accessor ().
+
+ The abstract operation InitializeNumberFormat accepts the arguments numberFormat (which must be an object), locales, and options. It initializes numberFormat as a NumberFormat object. The following steps are taken:
+
+
+
+
Let requestedLocales be ? CanonicalizeLocaleList(locales).
Set numberFormat.[[PositivePattern]] to stylePatterns.[[positivePattern]].
Set numberFormat.[[NegativePattern]] to stylePatterns.[[negativePattern]].
Return numberFormat.
+
+
+
+
+
1.1.3CurrencyDigits ( currency )
+
+
+ When the abstract operation CurrencyDigits is called with an argument currency (which must be an upper case String value), the following steps are taken:
+
+
+
+
If the ISO 4217 currency and funds code list contains currency as an alphabetic code, return the minor unit value corresponding to the currency from the list; otherwise, return 2.
+
+
+
+
+
1.1.4Number Format Functions
+
+
A Number format function is an anonymous built-in function that has a [[NumberFormat]] internal slot.
+
When a Number format function F is called with optional argument value, the following steps are taken:
+
+
Let nf be F.[[NumberFormat]].
Assert: Type(nf) is Object and nf has an [[InitializedNumberFormat]] internal slot.
+ The length property of a Number format function is 1.
+
+
+
+
+
+
1.1.5FormatNumberToString ( intlObject, x )
+
+
+ The FormatNumberToString abstract operation is called with arguments intlObject (which must be an object with [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], and [[MaximumFractionDigits]] internal slots), and x (which must be a Number value), and returns a Record containing two values: x as a string value with digits formatted according to the five formatting parameters in the field [[FormattedString]], and the final floating decimal value of x after rounding has been performed in the field [[RoundedNumber]].
+
+
+
+
+
If intlObject.[[MinimumSignificantDigits]] and intlObject.[[MaximumSignificantDigits]] are both not undefined, then
Let result be ToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]]).
Else,
Let result be ToRawFixed(x, intlObject.[[MinimumIntegerDigits]], intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]]).
Return result.
+
+
+
+
Let isNegative be x < 0 or x is -0.
If isNegative, then
Let x be -x.
If intlObject.[[RoundingType]] is "significantDigits", then
Let result be ToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]]).
Else If intlObject.[[RoundingType]] is "fractionDigits", then,
Let result be ToRawFixed(x, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]]).
Else,
Assert: intlObject.[[RoundingType]] is "compactRounding".
Let minInteger be intlObject.[[MinimumIntegerDigits]].
If int < minInteger, then
Let forwardZeros be the String consisting of minInteger–int occurrences of the character "0".
Let string be the concatenation of Strings forwardZeros and string.
If isNegative, then
Let x be -x.
Return the Record { [[RoundedNumber]]: x, [[FormattedString]]: string }.
+
+
+
+
+
+
1.1.6PartitionNumberPattern ( numberFormat, x )
+
+
+ The PartitionNumberPattern abstract operation is called with arguments numberFormat (which must be an object initialized as a NumberFormat) and x (which must be a Number value), interprets x as a numeric value, and creates the corresponding parts according to the effective locale and the formatting options of numberFormat. The following steps are taken:
+
+
+
+
If x is not NaN and x < 0 or x is -0, then
Let x be -x.
Let pattern be numberFormat.[[NegativePattern]].
Else,
Let pattern be numberFormat.[[PositivePattern]].
Let exponent be 0.
If x is NaN, then
Let n be an implementation- and locale-dependent (ILD) String value indicating the NaN value.
Else if x is not a finite Number,
Let n be an ILD String value indicating infinity.
Else,
If numberFormat.[[Style]] is "percent", let x be 100 × x.
If the numberFormat.[[NumberingSystem]] matches one of the values in the "Numbering System" column of Table 1 below, then
Let digits be a List whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the "Digits" column of the matching row in Table 1.
Replace each digit in n with the value of digits[digit].
Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
Let decimalSepIndex be Call(%StringProto_indexOf%, n, « ".", 0 »).
If decimalSepIndex > 0, then
Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive.
Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.
Else,
Let integer be n.
Let fraction be undefined.
If the numberFormat.[[UseGrouping]] is true, then
Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer.
Assert: The number of elements in groupsList is greater than 0.
Append a new Record { [[Type]]: "group", [[Value]]: groupSepSymbol } as the last element of result.
Else,
Append a new Record { [[Type]]: "integer", [[Value]]: integer } as the last element of result.
If fraction is not undefined, then
Let decimalSepSymbol be the ILND String representing the decimal separator.
Append a new Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } as the last element of result.
Append a new Record { [[Type]]: "fraction", [[Value]]: fraction } as the last element of result.
Else if p is equal to "plusSign", then
Let plusSignSymbol be the ILND String representing the plus sign.
Append a new Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } as the last element of result.
Else if p is equal to "minusSign", then
Let minusSignSymbol be the ILND String representing the minus sign.
Append a new Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } as the last element of result.
Else if p is equal to "compactSymbol", then
Let compactSymbol be an ILD string representing exponent in short form, which may depend on x in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a "{compactSymbol}" placeholder.
Append a new Record { [[Type]]: "compact", [[Value]]: compactSymbol } as the last element of result.
Else if p is equal to "compactName", then
Let compactName be an ILD string representing exponent in long form, which may depend on x in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a "{compactName}" placeholder.
Append a new Record { [[Type]]: "compact", [[Value]]: compactName } as the last element of result.
Else if p is equal to "scientificSeparator", then
Let scientificSeparator be the ILND String representing the exponent separator.
Append a new Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } as the last element of result.
Else if p is equal to "scientificExponent", then
If exponent < 0, then
Let minusSignSymbol be the ILND String representing the minus sign.
Append a new Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } as the last element of result.
Let exponent be -exponent.
Let exponentResult be ToRawFixed(exponent, 1, 0, 0).
Append a new Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } as the last element of result.
Else if p is equal to "percentSign"and numberFormat.[[Style]] is "percent", then
Let percentSignSymbol be the ILND String representing the percent sign.
Append a new Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } as the last element of result.
Else if p is equal to "unitSymbol" and numberFormat.[[Style]] is "unit" or "percent", then
Let unit be numberFormat.[[Unit]].
Let mu be an ILD string representing unit in short form, which may depend on x in languages having different plural forms.
Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result.
Else if p is equal to "unitNarrowSymbol" and numberFormat.[[Style]] is "unit" or "percent", then
Let unit be numberFormat.[[Unit]].
Let mu be an ILD string representing unit in narrow form, which may depend on x in languages having different plural forms.
Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result.
Else if p is equal to "unitName" and numberFormat.[[Style]] is "unit" or "percent", then
Let unit be numberFormat.[[Unit]].
Let mu be an ILD string representing unit in long form, which may depend on x in languages having different plural forms.
Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result.
Else if p is equal to "currency" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Assert: numberFormat.[[CurrencyDisplay]] is "code", "symbol" or "name".
If numberFormat.[[CurrencyDisplay]] is "code", then
Let cd be currency.
Else if numberFormat.[[CurrencyDisplay]] is "symbol", then
Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, use currency itself.
Else if numberFormat.[[CurrencyDisplay]] is "name", then
Let cd be an ILD string representing currency in long form. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencyCode" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be currency.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencySymbol" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencyNarrowSymbol" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be an ILD string representing currency in narrow form. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencyName" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be an ILD string representing currency in long form, which may depend on x in languages having different plural forms. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else,
Let unknown be an ILND String based on x and p.
Append a new Record { [[Type]]: "unknown", [[Value]]: unknown } as the last element of result.
Set nextIndex to endIndex + 1.
Set beginIndex to Call(%StringProto_indexOf%, pattern, « "{", nextIndex »).
If nextIndex is less than length, then
Let literal be the substring of pattern from position nextIndex, inclusive, to position length, exclusive.
Append a new Record { [[Type]]: "literal", [[Value]]: literal } as the last element of result.
Return result.
+
+
+
Table 1: Numbering systems with simple digit mappings
+
+
+ The computations rely on String values and locations within numeric strings that are dependent upon the implementation and the effective locale of numberFormat ("ILD") or upon the implementation, the effective locale, and the numbering system of numberFormat ("ILND"). The ILD and ILND Strings mentioned, other than those for currency names, must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
+
+
+ Note 2
+ It is recommended that implementations use the locale provided by the Common Locale Data Repository (available at http://cldr.unicode.org/).
+
+
+
+
+
+
1.1.7FormatNumber( numberFormat, x )
+
+
+ The FormatNumber abstract operation is called with arguments numberFormat (which must be an object initialized as a NumberFormat) and x (which must be a Number value), and performs the following steps:
+
+
Set result to a String value produced by concatenating result and part.[[Value]].
Return result.
+
+
+
+
+
1.1.8FormatNumberToParts( numberFormat, x )
+
+
+ The FormatNumberToParts abstract operation is called with arguments numberFormat (which must be an object initialized as a NumberFormat) and x (which must be a Number value), and performs the following steps:
+
+
+ When the ToRawPrecision abstract operation is called with arguments x (which must be a finite non-negative number), minPrecision, and maxPrecision (both must be integers between 1 and 21), the following steps are taken:
+
+
+
+
Let p be maxPrecision.
If x = 0, then
Let m be the String consisting of p occurrences of the character "0".
Let e be 0.
Let xFinal be 0.
Else,
Let e and n be integers such that 10p–1 ≤ n < 10p and for which the exact mathematical value of n × 10e–p+1 – x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e–p+1 is larger.
Let e be the base 10 logarithm of x rounded down to the nearest integer.
Let n be an integer such that 10p–1 ≤ n < 10p and for which the exact mathematical value of n × 10e–p+1 – x is as close to zero as possible. If there is more than one such n, pick the one for which n × 10e–p+1 is larger.
Let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
Let xFinal be n × 10e–p+1.
If e ≥ p, then
Return the concatenation of m and e-p+1 occurrences of the character "0".
If e = p-1, then
Return m.
If e ≥ p–1, then
Let m be the concatenation of m and e–p+1 occurrences of the character "0".
Let int be e+1.
Else If e ≥ 0, then
Let m be the concatenation of the first e+1 characters of m, the character ".", and the remaining p–(e+1) characters of m.
Let int be e+1.
If e < 0, thenElse,
Assert: e < 0.
Let m be the concatenation of the String "0.", –(e+1) occurrences of the character "0", and the string m.
Let int be 1.
If m contains the character ".", and maxPrecision > minPrecision, then
Let cut be maxPrecision – minPrecision.
Repeat, while cut > 0 and the last character of m is "0"
Remove the last character from m.
Decrease cut by 1.
If the last character of m is ".", then
Remove the last character from m.
Return m.
Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int }.
+
+ When the ToRawFixed abstract operation is called with arguments x (which must be a finite non-negative number), minInteger (which must be an integer between 1 and 21), minFraction, and maxFraction (which must be integers between 0 and 20), the following steps are taken:
+
+
+
+
Let f be maxFraction.
Let n be an integer for which the exact mathematical value of n ÷ 10f – x is as close to zero as possible. If there are two such n, pick the larger n.
Let xFinal be n ÷ 10f.
If n = 0, let m be the String "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
If f ≠ 0, then
Let k be the number of characters in m.
If k ≤ f, then
Let z be the String consisting of f+1–k occurrences of the character "0".
Let m be the concatenation of Strings z and m.
Let k be f+1.
Let a be the first k–f characters of m, and let b be the remaining f characters of m.
Let m be the concatenation of the three Strings a, ".", and b.
Let int be the number of characters in a.
Else, let int be the number of characters in m.
Let cut be maxFraction – minFraction.
Repeat, while cut > 0 and the last character of m is "0"
Remove the last character from m.
Decrease cut by 1.
If the last character of m is ".", then
Remove the last character from m.
If int < minInteger, then
Let z be the String consisting of minInteger–int occurrences of the character "0".
Let m be the concatenation of Strings z and m.
Return m.
Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int }.
+
+
+
+
+
1.1.11UnwrapNumberFormat( nf )
+
+ The UnwrapNumberFormat abstract operation gets the underlying NumberFormat operation
+ for various methods which implement ECMA-402 v1 semantics for supporting initializing
+ existing Intl objects.
+
+
+ The abstract operation GetNumberFormatPattern considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted and returns a pattern, a String value as described in 1.3.3.
+
+
Let currencyDisplay be numberFormat.[[CurrencyDisplay]].
Let currencySign be numberFormat.[[CurrencySign]].
Let patterns be patterns.[["currency"]].
If patterns.[[<currency>]] is undefined, then
Let currency be "fallback".
Let patterns be patterns.[[<currency>]].
Let patterns be patterns.[[<currencyDisplay>]].
Let patterns be patterns.[[<currencySign>]].
Else,
Assert: style is "decimal".
Let patterns be patterns.[["decimal"]].
Let signDisplay be numberFormat.[[SignDisplay]].
Let patterns be patterns.[[<signDisplay>]].
Let notation be numberFormat.[[Notation]].
Let displayNotation be "standard".
If notation is "scientific" or notation is "engineering", then
Let displayNotation be "scientific".
Else If exponent is not 0, then
Assert: notation is "compact".
Let compactDisplay be numberFormat.[[CompactDisplay]].
If compactDisplay is "short", then
Let displayNotation be "compactShort".
Else,
Assert: compactDisplay is "long".
Let displayNotation be "compactLong".
Let patterns be patterns.[[<displayNotation>]].
If x is not NaN and x < 0 or x is -0, then
Let pattern be patterns.[[negativePattern]].
Else If x is 0, then
Let pattern be patterns.[[zeroPattern]].
Else,
Let pattern be patterns.[[positivePattern]].
Return pattern.
+
+
+
+
+
+
+
1.1.14ComputeExponent ( numberFormat, x )
+
+ The abstract operation ComputeExponent computes an exponent (power of ten) by which to scale x according to the number formatting settings. It handles cases such as 999 rounding up to 1000, requiring a different exponent.
+
+
+
If x = 0, then
Return 0.
If x < 0, then
Let x = -x.
Let magnitude be the base 10 logarithm of x rounded down to the nearest integer.
+ The abstract operation ComputeExponentHelper computes an exponent by which to scale a number of the given magnitude (power of ten of the most significant digit) according to the locale and the desired notation (scientific, engineering, or compact).
+
+
+
Let notation be numberFormat.[[Notation]].
If notation is "standard", then
Return 0.
Else If notation is "scientific", then
Return magnitude.
Else If notation is "engineering", then
Let thousands be the greatest integer that is not greater than magnitude ÷ 3.
Return thousands × 3.
Else,
Assert: notation is "compact".
Let exponent be an implementation-dependent integer by which to scale a number of the given magnitude in compact notation for the current locale.
Return exponent.
+
+
+
+
+
+
+
1.2The Intl.NumberFormat Constructor
+
+
+ The NumberFormat constructor is the %NumberFormat% intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in .
+
+
+ The value of the length property of the supportedLocalesOf method is 1.
+
+
+
+
+
+
1.3.3Internal slots
+
+
+ The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in .
+
+
+
+
+ The value of the [[RelevantExtensionKeys]] internal slot is « "nu" ».
+
+
+
+ Note 1
+ Unicode Technical Standard 35 describes two locale extension keys that are relevant to number formatting, "nu" for numbering system and "cu" for currency. Intl.NumberFormat, however, requires that the currency of a currency format is specified through the currency property in the options objects.
+
+
+
+
+ The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in and the following additional constraints:
+
+
+
+
+
The list that is the value of the "nu" field of any locale field of [[LocaleData]] must not include the values "native", "traditio", or "finance".
+
[[LocaleData]][locale] must have a patterns field for all locale values. The value of this field must be a recordRecord, which must have fields with the names of the three number format styles: "decimal", "percent", and "currency". Each of these fields in turn must be a record with the fields positivePattern and negativePattern. three fields: "decimal", "currency", and "unit".
+
The two fields "currency" and "unit" noted above must be Records with at least one field, "fallback". The "currency" may have additional fields with keys corresponding to currency codes according to . Each field of "currency" must be a Record with fields corresponding to the possible currencyDisplay values: "code", "symbol", "narrowSymbol", and "name". Each of those fields must contain a Record with fields corresponding to the possible currencySign values: "standard" or "accounting". The "unit" field (of [[LocaleData]][locale]) may have additional fields beyond the required field "fallback" with keys corresponding to measurement core unit identifiers corresponding to . Each field of "unit" must be a Record with fields corresponding to the possible unitDisplay values: "narrow", "short", and "long".
+
All of the leaf fields so far described for the patterns tree ("decimal", great-grandchildren of "currency", and grandchildren of "unit") must be Records with fields corresponding to the possible signDisplay values: "auto", "always", "never", and "exceptZero". Each of these fields must be a Record with the keys "standard", "scientific", "compactShort", and "compactLong". Each of these fields must be a Record with the keys "positivePattern", "zeroPattern", and "negativePattern".
+
The value of these fields the aforementioned fields (the sign-dependent pattern fields) must be string values that must contain the substring "{number}" and may contain the substrings "{plusSign}", and"{minusSign}", "{compactSymbol}", "{compactName}", "{scientificSeparator}", and "{scientificExponent}"; the values within the percent field must also contain the substring "{percentSign}"; the values within the currency"currency" field must also contain the substring "{currency}" one of the following substrings: "{currencyCode}", "{currencySymbol}", "{currencyNarrowSymbol}", or "{currencyName}"; and the values within the "unit" field must also contain one of the following substrings: "{percentSign}", "{unitSymbol}", "{unitNarrowSymbol}", or "{unitName}". The pattern strings must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
+
+ Note 2
+ It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at http://cldr.unicode.org/).
+
+
+
+
+
+
+
1.4Properties of the Intl.NumberFormat Prototype Object
+
+
+ The Intl.NumberFormat prototype object is itself an ordinary object. %NumberFormatPrototype% is not an Intl.NumberFormat instance and does not have an [[InitializedNumberFormat]] internal slot or any of the other internal slots of Intl.NumberFormat instance objects.
+
+
+
+
+
1.4.1Intl.NumberFormat.prototype.constructor
+
+
+ The initial value of Intl.NumberFormat.prototype.constructor is the intrinsic object %NumberFormat%.
+
+
+ The initial value of the @@toStringTag property is the string value "Object".
+
+
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+
+
+
+
+
+
1.4.3get Intl.NumberFormat.prototype.format
+
+
+ Intl.NumberFormat.prototype.format is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:
+
+
+
+
Let nf be the this value.
If Type(nf) is not Object, throw a TypeError exception.
Let F be a new built-in function object as defined in Number Format Functions (1.1.4).
Set F.[[NumberFormat]] to nf.
Set nf.[[BoundFormat]] to F.
Return nf.[[BoundFormat]].
+
+
+ Note
+ The returned function is bound to nf so that it can be passed directly to Array.prototype.map or other functions.
+ This is considered a historical artefact, as part of a convention which is no longer followed for new features, but is preserved to maintain compatibility with existing programs.
+
+
+
+
+
+
1.4.4Intl.NumberFormat.prototype.formatToParts ( value )
+
+
+ When the formatToParts method is called with an optional argument value, the following steps are taken:
+
+
+
+
Let nf be the this value.
If Type(nf) is not Object, throw a TypeError exception.
If nf does not have an [[InitializedNumberFormat]] internal slot, throw a TypeError exception.
+ Intl.NumberFormat instances have an [[InitializedNumberFormat]] internal slot.
+
+
+
+
+ Intl.NumberFormat instances also have several internal slots that are computed by the constructor:
+
+
+
+
+
[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.
+
[[DataLocale]] is a String value with the language tag of the nearest locale for which the implementation has data to perform the formatting operation. It will be a parent locale of [[Locale]].
+
[[NumberingSystem]] is a String value with the "type" given in Unicode Technical Standard 35 for the numbering system used for formatting.
+
[[Style]] is one of the String values "decimal", "currency", or"percent", or "unit", identifying the number format style usedthe type of quantity being measured.
+
[[Currency]] is a String value with the currency code identifying the currency to be used if formatting with the "currency"styleunit type. It is only used when [[Style]] has the value "currency".
+
[[CurrencyDisplay]] is one of the String values "code", "symbol", "narrowSymbol", or "name", specifying whether to display the currency as an ISO 4217 alphabetic currency code, a localized currency symbol, or a localized currency name if formatting with the "currency" style. It is only used when [[Style]] has the value "currency".
+
[[CurrencySign]] is one of the String values "standard" or "accounting", specifying whether to render negative numbers in accounting format, often signified by parenthesis. It is only used when [[Style]] has the value "currency" and when [[SignDisplay]] is not "never".
+
[[Unit]] is a core unit identifier, as defined by Unicode Technical Standard #35, Part 2, Section 6. It is only used when [[Style]] has the value "unit" or "percent".
+
[[UnitDisplay]] is one of the String values "short", "narrow", or "long", specifying whether to display the unit as a symbol, narrow symbol, or localized long name if formatting with the "unit" or "percent" style. It is only used when [[Style]] has the value "unit" or "percent".
+
[[MinimumIntegerDigits]] is a non-negative integer Number value indicating the minimum integer digits to be used. Numbers will be padded with leading zeroes if necessary.
+
[[MinimumFractionDigits]] and [[MaximumFractionDigits]] are non-negative integer Number values indicating the minimum and maximum fraction digits to be used. Numbers will be rounded or padded with trailing zeroes if necessary. These properties are only used when [[RoundingType]] is "fractionDigits".
+
[[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] are positive integer Number values indicating the minimum and maximum fraction digits to be shown. Either none or both of these properties are present; if they are, they override minimum and maximum integer and fraction digits – If present, the formatter uses however many integer and fraction digits are required to display the specified number of significant digits. These properties are only used when [[RoundingType]] is "significantDigits".
+
[[UseGrouping]] is a Boolean value indicating whether a grouping separator should be used.
+
[[RoundingType]] is one of the String values "fractionDigits", "significantDigits", or "compactRounding", indicating which rounding strategy to use. If "fractionDigits", the number is rounded according to [[MinimumFractionDigits]] and [[MaximumFractionDigits]], as described above. If "significantDigits", the number is rounded according to [[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] as described above. If "compactRounding", the number is rounded to 1 maximum fraction digit if there is 1 digit before the decimal separator, and otherwise round to 0 fraction digits.
+
[[Notation]] is one of the String values "standard", "scientific", "engineering", or "compact", specifying whether the number should be displayed without scaling, scaled to the units place with the power of ten in scientific notation, scaled to the nearest thousand with the power of ten in scientific notation, or scaled to the nearest locale-dependent compact decimal notation power of ten with the corresponding compact decimal notation affix.
+
[[CompactDisplay]] is one of the String values "short" or "long", specifying whether to display compact notation affixes in short form ("5K") or long form ("5 thousand") if formatting with the "compact" notation. It is only used when [[Notation]] has the value "compact".
+
[[SignDisplay]] is one of the String values "auto", "always", "never", or "exceptZero", specifying whether to show the sign on negative numbers only, positive and negative numbers including zero, neither positive nor negative numbers, or positive and negative numbers but not zero.
+
[[PositivePattern]] and [[NegativePattern]] are String values as described in 1.3.3.
+
+
+
+ Finally, Intl.NumberFormat instances have a [[BoundFormat]] internal slot that caches the function returned by the format accessor (1.4.3).
+
+
+
+
+
\ No newline at end of file
diff --git a/numberformat_proposed.html b/section11/numberformat_proposed.html
similarity index 56%
rename from numberformat_proposed.html
rename to section11/numberformat_proposed.html
index 979c8f5..8c3049d 100644
--- a/numberformat_proposed.html
+++ b/section11/numberformat_proposed.html
@@ -14,22 +14,33 @@
SetNumberFormatDigitOptions ( _intlObj_, _options_, _mnfdDefault_, _mxfdDefa
1. Assert: Type(_intlObj_) is Object.
1. Assert: Type(_options_) is Object.
- 1. Assert: type(_mnfdDefault_) is Number.
- 1. Assert: type(_mxfdDefault_) is Number.
+ 1. Assert: Type(_mnfdDefault_) is Number.
+ 1. Assert: Type(_mxfdDefault_) is Number.
1. Let _mnid_ be ? GetNumberOption(_options_, `"minimumIntegerDigits,"`, 1, 21, 1).
- 1. Let _mnfd_ be ? GetNumberOption(_options_, `"minimumFractionDigits"`, 0, 20, _mnfdDefault_).
- 1. Let _mxfdActualDefault_ be max( _mnfd_, _mxfdDefault_ ).
- 1. Let _mxfd_ be ? GetNumberOption(_options_, `"maximumFractionDigits"`, _mnfd_, 20, _mxfdActualDefault_).
+ 1. Let _mnfd_ be ? Get(_options_, `"minimumFractionDigits"`).
+ 1. Let _mxfd_ be ? Get(_options_, `"maximumFractionDigits"`).
1. Let _mnsd_ be ? Get(_options_, `"minimumSignificantDigits"`).
1. Let _mxsd_ be ? Get(_options_, `"maximumSignificantDigits"`).
- 1. Set _intlObj_.[[MinimumIntegerDigits]] to mnid.
- 1. Set _intlObj_.[[MinimumFractionDigits]] to mnfd.
- 1. Set _intlObj_.[[MaximumFractionDigits]] to mxfd.
+ 1. Set _intlObj_.[[MinimumIntegerDigits]] to _mnid_.
1. If _mnsd_ is not *undefined* or _mxsd_ is not *undefined*, then
+ 1. Set _intlObj_.[[RoundingType]] to `"significantDigits"`.
1. Let _mnsd_ be ? DefaultNumberOption(_mnsd_, 1, 21, 1).
1. Let _mxsd_ be ? DefaultNumberOption(_mxsd_, _mnsd_, 21, 21).
- 1. Set _intlObj_.[[MinimumSignificantDigits]] to mnsd.
- 1. Set _intlObj_.[[MaximumSignificantDigits]] to mxsd.
+ 1. Set _intlObj_.[[MinimumSignificantDigits]] to _mnsd_.
+ 1. Set _intlObj_.[[MaximumSignificantDigits]] to _mxsd_.
+ 1. Else If _mnfd_ is not *undefined* or _mxfd_ is not *undefined*, then
+ 1. Set _intlObj_.[[RoundingType]] to `"fractionDigits"`.
+ 1. Let _mnfd_ be ? DefaultNumberOption(_mnfd_, 0, 20, _mnfdDefault_).
+ 1. Let _mxfdActualDefault_ be max( _mnfd_, _mxfdDefault_ ).
+ 1. Let _mxfd_ be ? DefaultNumberOption(_mxfd_, _mnfd_, 20, _mxfdActualDefault_).
+ 1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfd_.
+ 1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfd_.
+ 1. Else If _intlObj_.[[Notation]] is `"compact"`, then
+ 1. Set _intlObj_.[[RoundingType]] to `"compactRounding"`.
+ 1. Else,
+ 1. Set _intlObj_.[[RoundingType]] to `"fractionDigits"`.
+ 1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfdDefault_.
+ 1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfdDefault_.
1. Let _localeData_ be %NumberFormat%.[[LocaleData]].
1. Let _r_ be ResolveLocale(%NumberFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %NumberFormat%.[[RelevantExtensionKeys]], _localeData_).
1. Set _numberFormat_.[[Locale]] to _r_.[[locale]].
+ 1. Set _numberFormat_.[[DataLocale]] to _r_.[[dataLocale]].
1. Set _numberFormat_.[[NumberingSystem]] to _r_.[[nu]].
- 1. Let _dataLocale_ be _r_.[[dataLocale]].
- 1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, « `"decimal"`, `"percent"`, `"currency"` », `"decimal"`).
- 1. Set _numberFormat_.[[Style]] to _style_.
- 1. Let _currency_ be ? GetOption(_options_, `"currency"`, `"string"`, *undefined*, *undefined*).
- 1. If _currency_ is not *undefined*, then
- 1. If the result of IsWellFormedCurrencyCode(_currency_) is *false*, throw a *RangeError* exception.
- 1. If _style_ is `"currency"` and _currency_ is *undefined*, throw a *TypeError* exception.
+ 1. Perform ? SetNumberFormatUnitOptions(_numberFormat_, _options_).
+ 1. Let _style_ be _numberFormat_.[[Style]].
1. If _style_ is `"currency"`, then
- 1. Let _currency_ be the result of converting _currency_ to upper case as specified in .
- 1. Set _numberFormat_.[[Currency]] to _currency_.
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
1. Let _cDigits_ be CurrencyDigits(_currency_).
- 1. Let _currencyDisplay_ be ? GetOption(_options_, `"currencyDisplay"`, `"string"`, « `"code"`, `"symbol"`, `"name"` », `"symbol"`).
- 1. If _style_ is `"currency"`, set _numberFormat_.[[CurrencyDisplay]] to _currencyDisplay_.
- 1. If _style_ is `"currency"`, then
1. Let _mnfdDefault_ be _cDigits_.
1. Let _mxfdDefault_ be _cDigits_.
1. Else,
@@ -75,15 +78,16 @@
1. Let _mxfdDefault_ be 0.
1. Else,
1. Let _mxfdDefault_ be 3.
+ 1. Let _notation_ be ? GetOption(_options_, `"notation"`, `"string"`, « `"standard"`, `"scientific"`, `"engineering"`, `"compact"` », `"standard"`).
+ 1. Set _numberFormat_.[[Notation]] to _notation_.
1. Perform ? SetNumberFormatDigitOptions(_numberFormat_, _options_, _mnfdDefault_, _mxfdDefault_).
+ 1. Let _compactDisplay_ be ? GetOption(_options_, `"compactDisplay"`, `"string"`, « `"short"`, `"long"` », `"short"`).
+ 1. If _notation_ is `"compact"`, then
+ 1. Set _numberFormat_.[[CompactDisplay]] to _compactDisplay_.
1. Let _useGrouping_ be ? GetOption(_options_, `"useGrouping"`, `"boolean"`, *undefined*, *true*).
1. Set _numberFormat_.[[UseGrouping]] to _useGrouping_.
- 1. Let _dataLocaleData_ be _localeData_.[[<_dataLocale_>]].
- 1. Let _patterns_ be _dataLocaleData_.[[patterns]].
- 1. Assert: _patterns_ is a record (see ).
- 1. Let _stylePatterns_ be _patterns_.[[<_style_>]].
- 1. Set _numberFormat_.[[PositivePattern]] to _stylePatterns_.[[positivePattern]].
- 1. Set _numberFormat_.[[NegativePattern]] to _stylePatterns_.[[negativePattern]].
+ 1. Let _signDisplay_ be ? GetOption(_options_, `"signDisplay"`, `"string"`, « `"auto"`, `"never"`, `"always"`, `"exceptZero"` », `"auto"`).
+ 1. Set _numberFormat_.[[SignDisplay]] to _signDisplay_.
1. Return _numberFormat_.
@@ -123,15 +127,32 @@
Number Format Functions
FormatNumberToString ( _intlObject_, _x_ )
- The FormatNumberToString abstract operation is called with arguments _intlObject_ (which must be an object with [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], and [[MaximumFractionDigits]] internal slots), and _x_ (which must be a Number value), and returns _x_ as a string value with digits formatted according to the five formatting parameters.
+ The FormatNumberToString abstract operation is called with arguments _intlObject_ (which must be an object with [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], and [[MaximumFractionDigits]] internal slots), and _x_ (which must be a Number value), and returns a Record containing two values: _x_ as a string value with digits formatted according to the five formatting parameters in the field [[FormattedString]], and the final floating decimal value of _x_ after rounding has been performed in the field [[RoundedNumber]].
- 1. If _intlObject_.[[MinimumSignificantDigits]] and _intlObject_.[[MaximumSignificantDigits]] are both not *undefined*, then
+ 1. Let _isNegative_ be _x_ < 0 or _x_ is *-0*.
+ 1. If _isNegative_, then
+ 1. Let _x_ be -_x_.
+ 1. If _intlObject_.[[RoundingType]] is `"significantDigits"`, then
1. Let _result_ be ToRawPrecision(_x_, _intlObject_.[[MinimumSignificantDigits]], _intlObject_.[[MaximumSignificantDigits]]).
+ 1. Else If _intlObject_.[[RoundingType]] is `"fractionDigits"`, then,
+ 1. Let _result_ be ToRawFixed(_x_, _intlObject_.[[MinimumFractionDigits]], _intlObject_.[[MaximumFractionDigits]]).
1. Else,
- 1. Let _result_ be ToRawFixed(_x_, _intlObject_.[[MinimumIntegerDigits]], _intlObject_.[[MinimumFractionDigits]], _intlObject_.[[MaximumFractionDigits]]).
- 1. Return _result_.
+ 1. Assert: _intlObject_.[[RoundingType]] is `"compactRounding"`.
+ 1. Let _result_ be ToRawFixed(_x_, 0, 0).
+ 1. If _result_.[[IntegerDigitsCount]] = 1, then
+ 1. Let _result_ be ToRawPrecision(_x_, 1, 2).
+ 1. Let _x_ be _result_.[[RoundedNumber]].
+ 1. Let _string_ be _result_.[[FormattedString]].
+ 1. Let _int_ be _result_.[[IntegerDigitsCount]].
+ 1. Let _minInteger_ be _intlObject_.[[MinimumIntegerDigits]].
+ 1. If _int_ < _minInteger_, then
+ 1. Let _forwardZeros_ be the String consisting of _minInteger_–_int_ occurrences of the character `"0"`.
+ 1. Let _string_ be the concatenation of Strings _forwardZeros_ and _string_.
+ 1. If _isNegative_, then
+ 1. Let _x_ be -_x_.
+ 1. Return the Record { [[RoundedNumber]]: _x_, [[FormattedString]]: _string_ }.
@@ -143,11 +164,19 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
- 1. If _x_ is not *NaN* and _x_ < 0, then
- 1. Let _x_ be -_x_.
- 1. Let _pattern_ be _numberFormat_.[[NegativePattern]].
+ 1. Let _exponent_ be 0.
+ 1. If _x_ is *NaN*, then
+ 1. Let _n_ be an implementation- and locale-dependent (ILD) String value indicating the *NaN* value.
+ 1. Else if _x_ is not a finite Number,
+ 1. Let _n_ be an ILD String value indicating infinity.
1. Else,
- 1. Let _pattern_ be _numberFormat_.[[PositivePattern]].
+ 1. If _numberFormat_.[[Style]] is `"percent"`, let _x_ be 100 × _x_.
+ 1. Let _exponent_ be ComputeExponent(_numberFormat_, _x_).
+ 1. Let _x_ be _x_ × 10-_exponent_.
+ 1. Let _formatNumberResult_ be FormatNumberToString(_numberFormat_, _x_).
+ 1. Let _n_ be _formatNumberResult_.[[FormattedString]].
+ 1. Let _x_ be _formatNumberResult_.[[RoundedNumber]].
+ 1. Let _pattern_ be GetNumberFormatPattern(_numberFormat_, _x_, _exponent_)
1. Let _result_ be a new empty List.
1. Let _beginIndex_ be Call(%StringProto_indexOf%, _pattern_, « `"{"`, 0 »).
1. Let _endIndex_ be 0.
@@ -160,16 +189,12 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _literal_ be a substring of _pattern_ from position _nextIndex_, inclusive, to position _beginIndex_, exclusive.
1. Append a new Record { [[Type]]: `"literal"`, [[Value]]: _literal_ } as the last element of _result_.
1. Let _p_ be the substring of _pattern_ from position _beginIndex_, exclusive, to position _endIndex_, exclusive.
- 1. If _p_ is equal `"number"`, then
+ 1. If _p_ is equal to `"number"`, then
1. If _x_ is *NaN*, then
- 1. Let _n_ be an ILD String value indicating the *NaN* value.
1. Append a new Record { [[Type]]: `"nan"`, [[Value]]: _n_ } as the last element of _result_.
1. Else if _x_ is not a finite Number,
- 1. Let _n_ be an ILD String value indicating infinity.
1. Append a new Record { [[Type]]: `"infinity"`, [[Value]]: _n_ } as the last element of _result_.
1. Else,
- 1. If _numberFormat_.[[Style]] is `"percent"`, let _x_ be 100 × _x_.
- 1. Let _n_ be FormatNumberToString(_numberFormat_, _x_).
1. If the _numberFormat_.[[NumberingSystem]] matches one of the values in the `"Numbering System"` column of below, then
1. Let _digits_ be a List whose 10 String valued elements are the UTF-16 string representations of the 10 _digits_ specified in the `"Digits"` column of the matching row in .
1. Replace each _digit_ in _n_ with the value of _digits_[_digit_].
@@ -182,7 +207,7 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _integer_ be _n_.
1. Let _fraction_ be *undefined*.
1. If the _numberFormat_.[[UseGrouping]] is *true*, then
- 1. Let _groupSepSymbol_ be the ILND String representing the grouping separator.
+ 1. Let _groupSepSymbol_ be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
1. Let _groups_ be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the _integer_.
1. Assert: The number of elements in _groups_ List is greater than 0.
1. Repeat, while _groups_ List is not empty
@@ -196,28 +221,62 @@
PartitionNumberPattern ( _numberFormat_, _x_ )
1. Let _decimalSepSymbol_ be the ILND String representing the decimal separator.
1. Append a new Record { [[Type]]: `"decimal"`, [[Value]]: _decimalSepSymbol_ } as the last element of _result_.
1. Append a new Record { [[Type]]: `"fraction"`, [[Value]]: _fraction_ } as the last element of _result_.
- 1. Else if _p_ is equal `"plusSign"`, then
+ 1. Else if _p_ is equal to `"plusSign"`, then
1. Let _plusSignSymbol_ be the ILND String representing the plus sign.
1. Append a new Record { [[Type]]: `"plusSign"`, [[Value]]: _plusSignSymbol_ } as the last element of _result_.
- 1. Else if _p_ is equal `"minusSign"`, then
+ 1. Else if _p_ is equal to `"minusSign"`, then
1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
1. Append a new Record { [[Type]]: `"minusSign"`, [[Value]]: _minusSignSymbol_ } as the last element of _result_.
- 1. Else if _p_ is equal `"percentSign"` and _numberFormat_.[[Style]] is `"percent"`, then
+ 1. Else if _p_ is equal to `"compactSymbol"`, then
+ 1. Let _compactSymbol_ be an ILD string representing _exponent_ in short form, which may depend on _x_ in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a `"{compactSymbol}"` placeholder.
+ 1. Append a new Record { [[Type]]: `"compact"`, [[Value]]: _compactSymbol_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"compactName"`, then
+ 1. Let _compactName_ be an ILD string representing _exponent_ in long form, which may depend on _x_ in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a `"{compactName}"` placeholder.
+ 1. Append a new Record { [[Type]]: `"compact"`, [[Value]]: _compactName_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"scientificSeparator"`, then
+ 1. Let _scientificSeparator_ be the ILND String representing the exponent separator.
+ 1. Append a new Record { [[Type]]: `"exponentSeparator"`, [[Value]]: _scientificSeparator_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"scientificExponent"`, then
+ 1. If _exponent_ < 0, then
+ 1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
+ 1. Append a new Record { [[Type]]: `"exponentMinusSign"`, [[Value]]: _minusSignSymbol_ } as the last element of _result_.
+ 1. Let _exponent_ be -_exponent_.
+ 1. Let _exponentResult_ be ToRawFixed(_exponent_, 1, 0, 0).
+ 1. Append a new Record { [[Type]]: `"exponentInteger"`, [[Value]]: _exponentResult_.[[FormattedString]] } as the last element of _result_.
+ 1. Else if _p_ is equal to `"percentSign"`, then
1. Let _percentSignSymbol_ be the ILND String representing the percent sign.
1. Append a new Record { [[Type]]: `"percentSign"`, [[Value]]: _percentSignSymbol_ } as the last element of _result_.
- 1. Else if _p_ is equal `"currency"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Else if _p_ is equal to `"unitSymbol"` and _numberFormat_.[[Style]] is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _mu_ be an ILD string representing _unit_ in short form, which may depend on _x_ in languages having different plural forms.
+ 1. Append a new Record { [[Type]]: `"unit"`, [[Value]]: _mu_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"unitNarrowSymbol"` and _numberFormat_.[[Style]] is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _mu_ be an ILD string representing _unit_ in narrow form, which may depend on _x_ in languages having different plural forms.
+ 1. Append a new Record { [[Type]]: `"unit"`, [[Value]]: _mu_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"unitName"` and _numberFormat_.[[Style]] is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _mu_ be an ILD string representing _unit_ in long form, which may depend on _x_ in languages having different plural forms.
+ 1. Append a new Record { [[Type]]: `"unit"`, [[Value]]: _mu_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencyCode"` and _numberFormat_.[[Style]] is `"currency"`, then
1. Let _currency_ be _numberFormat_.[[Currency]].
- 1. Assert: _numberFormat_.[[CurrencyDisplay]] is `"code"`, `"symbol"` or `"name"`.
- 1. If _numberFormat_.[[CurrencyDisplay]] is `"code"`, then
- 1. Let _cd_ be _currency_.
- 1. Else if _numberFormat_.[[CurrencyDisplay]] is `"symbol"`, then
- 1. Let _cd_ be an ILD string representing _currency_ in short form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
- 1. Else if _numberFormat_.[[CurrencyDisplay]] is `"name"`, then
- 1. Let _cd_ be an ILD string representing _currency_ in long form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Let _cd_ be _currency_.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencySymbol"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be an ILD string representing _currency_ in short form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencyNarrowSymbol"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be an ILD string representing _currency_ in narrow form. If the implementation does not have such a representation of _currency_, use _currency_ itself.
+ 1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
+ 1. Else if _p_ is equal to `"currencyName"` and _numberFormat_.[[Style]] is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _cd_ be an ILD string representing _currency_ in long form, which may depend on _x_ in languages having different plural forms. If the implementation does not have such a representation of _currency_, use _currency_ itself.
1. Append a new Record { [[Type]]: `"currency"`, [[Value]]: _cd_ } as the last element of _result_.
1. Else,
- 1. Let _literal_ be the substring of _pattern_ from position _beginIndex_, inclusive, to position _endIndex_, inclusive.
- 1. Append a new Record { [[Type]]: `"literal"`, [[Value]]: _literal_ } as the last element of _result_.
+ 1. Let _unknown_ be an ILND String based on _x_ and _p_.
+ 1. Append a new Record { [[Type]]: `"unknown"`, [[Value]]: _unknown_ } as the last element of _result_.
1. Set _nextIndex_ to _endIndex_ + 1.
1. Set _beginIndex_ to Call(%StringProto_indexOf%, _pattern_, « `"{"`, _nextIndex_ »).
1. If _nextIndex_ is less than _length_, then
@@ -384,17 +443,22 @@
1. If _x_ = 0, then
1. Let _m_ be the String consisting of _p_ occurrences of the character `"0"`.
1. Let _e_ be 0.
+ 1. Let _xFinal_ be 0.
1. Else,
- 1. Let _e_ and _n_ be integers such that 10_p_–1 ≤ _n_ < 10_p_ and for which the exact mathematical value of _n_ × 10_e_–_p_+1 – _x_ is as close to zero as possible. If there are two such sets of _e_ and _n_, pick the _e_ and _n_ for which _n_ × 10_e_–_p_+1 is larger.
+ 1. Let _e_ be the base 10 logarithm of _x_ rounded down to the nearest integer.
+ 1. Let _n_ be an integer such that 10_p_–1 ≤ _n_ < 10_p_ and for which the exact mathematical value of _n_ × 10_e_–_p_+1 – _x_ is as close to zero as possible. If there is more than one such _n_, pick the one for which _n_ × 10_e_–_p_+1 is larger.
1. Let _m_ be the String consisting of the digits of the decimal representation of _n_ (in order, with no leading zeroes).
- 1. If _e_ ≥ _p_, then
- 1. Return the concatenation of _m_ and _e_-_p_+1 occurrences of the character `"0"`.
- 1. If _e_ = _p_-1, then
- 1. Return _m_.
- 1. If _e_ ≥ 0, then
+ 1. Let _xFinal_ be _n_ × 10_e_–_p_+1.
+ 1. If _e_ ≥ _p_–1, then
+ 1. Let _m_ be the concatenation of _m_ and _e_–_p_+1 occurrences of the character `"0"`.
+ 1. Let _int_ be _e_+1.
+ 1. Else If _e_ ≥ 0, then
1. Let _m_ be the concatenation of the first _e_+1 characters of _m_, the character `"."`, and the remaining _p_–(_e_+1) characters of _m_.
- 1. If _e_ < 0, then
+ 1. Let _int_ be _e_+1.
+ 1. Else,
+ 1. Assert: _e_ < 0.
1. Let _m_ be the concatenation of the String `"0."`, –(_e_+1) occurrences of the character `"0"`, and the string _m_.
+ 1. Let _int_ be 1.
1. If _m_ contains the character `"."`, and _maxPrecision_ > _minPrecision_, then
1. Let _cut_ be _maxPrecision_ – _minPrecision_.
1. Repeat, while _cut_ > 0 and the last character of _m_ is `"0"`
@@ -402,7 +466,7 @@
1. Decrease _cut_ by 1.
1. If the last character of _m_ is `"."`, then
1. Remove the last character from _m_.
- 1. Return _m_.
+ 1. Return the Record { [[FormattedString]]: _m_, [[RoundedNumber]]: _xFinal_, [[IntegerDigitsCount]]: _int_ }.
@@ -416,6 +480,7 @@
1. Let _f_ be _maxFraction_.
1. Let _n_ be an integer for which the exact mathematical value of _n_ ÷ 10_f_ – _x_ is as close to zero as possible. If there are two such _n_, pick the larger _n_.
+ 1. Let _xFinal_ be _n_ ÷ 10_f_.
1. If _n_ = 0, let _m_ be the String `"0"`. Otherwise, let _m_ be the String consisting of the digits of the decimal representation of _n_ (in order, with no leading zeroes).
1. If _f_ ≠ 0, then
1. Let _k_ be the number of characters in _m_.
@@ -433,10 +498,7 @@
1. Decrease _cut_ by 1.
1. If the last character of _m_ is `"."`, then
1. Remove the last character from _m_.
- 1. If _int_ < _minInteger_, then
- 1. Let _z_ be the String consisting of _minInteger_–_int_ occurrences of the character `"0"`.
- 1. Let _m_ be the concatenation of Strings _z_ and _m_.
- 1. Return _m_.
+ 1. Return the Record { [[FormattedString]]: _m_, [[RoundedNumber]]: _xFinal_, [[IntegerDigitsCount]]: _int_ }.
@@ -463,6 +525,140 @@
UnwrapNumberFormat( _nf_ )
See for the motivation of the normative optional text.
+
+
+
+ The abstract operation SetNumberFormatUnitOptions resolves the user-specified options relating to units onto the intl object.
+
+
+ 1. Assert: Type(_intlObj_) is Object.
+ 1. Assert: Type(_options_) is Object.
+ 1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, « `"decimal"`, `"percent"`, `"currency"`, `"unit"` », `"decimal"`).
+ 1. Set _intlObj_.[[Style]] to _style_.
+ 1. Let _currency_ be ? GetOption(_options_, `"currency"`, `"string"`, *undefined*, *undefined*).
+ 1. Let _currencyDisplay_ be ? GetOption(_options_, `"currencyDisplay"`, `"string"`, « `"code"`, `"symbol"`, `"narrowSymbol"`, `"name"` », `"symbol"`).
+ 1. Let _currencySign_ be ? GetOption(_options_, `"currencySign"`, `"string"`, « `"standard"`, `"accounting"` », `"standard"`).
+ 1. Let _unit_ be ? GetOption(_options_, `"unit"`, `"string"`, *undefined*, *undefined*).
+ 1. Let _unitDisplay_ be ? GetOption(_options_, `"unitDisplay"`, `"string"`, « `"short"`, `"narrow"`, `"long"` », `"short"`).
+ 1. If _style_ is `"currency"`, then
+ 1. If _currency_ is *undefined*, throw a *TypeError* exception.
+ 1. If the result of IsWellFormedCurrencyCode(_currency_) is *false*, throw a *RangeError* exception.
+ 1. Let _currency_ be the result of converting _currency_ to upper case as specified in .
+ 1. Set _intlObj_.[[Currency]] to _currency_.
+ 1. Set _intlObj_.[[CurrencyDisplay]] to _currencyDisplay_.
+ 1. Set _intlObj_.[[CurrencySign]] to _currencySign_.
+ 1. If _style_ is `"unit"`, then
+ 1. If _unit_ is *undefined*, throw a *TypeError* exception.
+ 1. If the result of IsWellFormedUnitIdentifier(_unit_) is *false*, throw a *RangeError* exception.
+ 1. Set _intlObj_.[[Unit]] to _unit_.
+ 1. Set _intlObj_.[[UnitDisplay]] to _unitDisplay_.
+
+
+
+
+
+ The abstract operation GetNumberFormatPattern considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted and returns a pattern, a String value as described in .
+
+
+ 1. Let _localeData_ be %NumberFormat%.[[LocaleData]].
+ 1. Let _dataLocale_ be _numberFormat_.[[DataLocale]].
+ 1. Let _dataLocaleData_ be _localeData_.[[<_dataLocale_>]].
+ 1. Let _patterns_ be _dataLocaleData_.[[patterns]].
+ 1. Assert: _patterns_ is a Record (see ).
+ 1. Let _style_ be _numberFormat_.[[Style]].
+ 1. If _style_ is `"percent"`, then
+ 1. Let _patterns_ be _patterns_.[[`"percent"`]].
+ 1. Else If _style_ is `"unit"`, then
+ 1. Let _unit_ be _numberFormat_.[[Unit]].
+ 1. Let _unitDisplay_ be _numberFormat_.[[UnitDisplay]].
+ 1. Let _patterns_ be _patterns_.[[`"unit"`]].
+ 1. If _patterns_.[[<_unit_>]] is *undefined*, then
+ 1. Let _unit_ be `"fallback"`.
+ 1. Let _patterns_ be _patterns_.[[<_unit_>]].
+ 1. Let _patterns_ be _patterns_.[[<_unitDisplay_>]].
+ 1. Else If _style_ is `"currency"`, then
+ 1. Let _currency_ be _numberFormat_.[[Currency]].
+ 1. Let _currencyDisplay_ be _numberFormat_.[[CurrencyDisplay]].
+ 1. Let _currencySign_ be _numberFormat_.[[CurrencySign]].
+ 1. Let _patterns_ be _patterns_.[[`"currency"`]].
+ 1. If _patterns_.[[<_currency_>]] is *undefined*, then
+ 1. Let _currency_ be `"fallback"`.
+ 1. Let _patterns_ be _patterns_.[[<_currency_>]].
+ 1. Let _patterns_ be _patterns_.[[<_currencyDisplay_>]].
+ 1. Let _patterns_ be _patterns_.[[<_currencySign_>]].
+ 1. Else,
+ 1. Assert: _style_ is `"decimal"`.
+ 1. Let _patterns_ be _patterns_.[[`"decimal"`]].
+ 1. Let _signDisplay_ be _numberFormat_.[[SignDisplay]].
+ 1. Let _patterns_ be _patterns_.[[<_signDisplay_>]].
+ 1. Let _notation_ be _numberFormat_.[[Notation]].
+ 1. Let _displayNotation_ be `"standard"`.
+ 1. If _notation_ is `"scientific"` or _notation_ is `"engineering"`, then
+ 1. Let _displayNotation_ be `"scientific"`.
+ 1. Else If _exponent_ is not 0, then
+ 1. Assert: _notation_ is `"compact"`.
+ 1. Let _compactDisplay_ be _numberFormat_.[[CompactDisplay]].
+ 1. If _compactDisplay_ is `"short"`, then
+ 1. Let _displayNotation_ be `"compactShort"`.
+ 1. Else,
+ 1. Assert: _compactDisplay_ is `"long"`.
+ 1. Let _displayNotation_ be `"compactLong"`.
+ 1. Let _patterns_ be _patterns_.[[<_displayNotation_>]].
+ 1. If _x_ is not *NaN* and _x_ < 0 or _x_ is *-0*, then
+ 1. Let _pattern_ be _patterns_.[[negativePattern]].
+ 1. Else If _x_ is 0, then
+ 1. Let _pattern_ be _patterns_.[[zeroPattern]].
+ 1. Else,
+ 1. Let _pattern_ be _patterns_.[[positivePattern]].
+ 1. Return _pattern_.
+
+
+
+
+
ComputeExponent ( _numberFormat_, _x_ )
+
+ The abstract operation ComputeExponent computes an exponent (power of ten) by which to scale _x_ according to the number formatting settings. It handles cases such as 999 rounding up to 1000, requiring a different exponent.
+
+
+ 1. If _x_ = 0, then
+ 1. Return 0.
+ 1. If _x_ < 0, then
+ 1. Let _x_ = -_x_.
+ 1. Let _magnitude_ be the base 10 logarithm of _x_ rounded down to the nearest integer.
+ 1. Let _exponent_ be ComputeExponentForMagnitude(_numberFormat_, _magnitude_).
+ 1. Let _x_ be _x_ × 10-_exponent_.
+ 1. Let _formatNumberResult_ be FormatNumberToString(_numberFormat_, _x_).
+ 1. If _formatNumberResult_.[[RoundedNumber]] = 0, then
+ 1. Return _exponent_.
+ 1. Let _newMagnitude_ be the base 10 logarithm of _x_ rounded down to the nearest integer.
+ 1. If _newMagnitude_ is _magnitude_ – _exponent_, then
+ 1. Return _exponent_.
+ 1. Return ComputeExponentForMagnitude(_numberFormat_, _magnitude_ + 1).
+
+
+
+
+
+ The abstract operation ComputeExponentHelper computes an exponent by which to scale a number of the given magnitude (power of ten of the most significant digit) according to the locale and the desired notation (scientific, engineering, or compact).
+
+
+ 1. Let _notation_ be _numberFormat_.[[Notation]].
+ 1. If _notation_ is `"standard"`, then
+ 1. Return 0.
+ 1. Else If _notation_ is `"scientific"`, then
+ 1. Return _magnitude_.
+ 1. Else If _notation_ is `"engineering"`, then
+ 1. Let _thousands_ be the greatest integer that is not greater than _magnitude_ ÷ 3.
+ 1. Return _thousands_ × 3.
+ 1. Else,
+ 1. Assert: _notation_ is `"compact"`.
+ 1. Let _exponent_ be an implementation-dependent integer by which to scale a number of the given magnitude in compact notation for the current locale.
+ 1. Return _exponent_.
+
+
@@ -481,7 +677,7 @@
1. If NewTarget is *undefined*, let _newTarget_ be the active function object, else let _newTarget_ be NewTarget.
- 1. Let _numberFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, `"%NumberFormatPrototype%"`, « [[InitializedNumberFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Currency]], [[CurrencyDisplay]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[UseGrouping]], [[PositivePattern]], [[NegativePattern]], [[BoundFormat]] »).
+ 1. Let _numberFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, `"%NumberFormatPrototype%"`, « [[InitializedNumberFormat]], [[Locale]], [[DataLocale]], [[NumberingSystem]], [[Style]], [[Unit]], [[UnitDisplay]], [[Currency]], [[CurrencyDisplay]], [[CurrencySign]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]], [[Notation]], [[CompactDisplay]], [[UseGrouping]], [[SignDisplay]], [[BoundFormat]] »).
1. Perform ? InitializeNumberFormat(_numberFormat_, _locales_, _options_).
@@ -556,7 +752,10 @@
Internal slots
The list that is the value of the `"nu"` field of any locale field of [[LocaleData]] must not include the values `"native"`, `"traditio"`, or `"finance"`.
-
[[LocaleData]][locale] must have a patterns field for all locale values. The value of this field must be a record, which must have fields with the names of the three number format styles: `"decimal"`, `"percent"`, and `"currency"`. Each of these fields in turn must be a record with the fields positivePattern and negativePattern. The value of these fields must be string values that must contain the substring `"{number}"` and may contain the substrings `"{plusSign}"`, and `"{minusSign}"`; the values within the percent field must also contain the substring `"{percentSign}"`; the values within the currency field must also contain the substring `"{currency}"`. The pattern strings must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
[[LocaleData]][locale] must have a patterns field for all locale values. The value of this field must be a Record, which must have fields with the names of the four number format styles: `"decimal"`, `"percent"`, `"currency"`, and `"unit"`.
+
The two fields `"currency"` and `"unit"` noted above must be Records with at least one field, `"fallback"`. The `"currency"` may have additional fields with keys corresponding to currency codes according to . Each field of `"currency"` must be a Record with fields corresponding to the possible currencyDisplay values: `"code"`, `"symbol"`, `"narrowSymbol"`, and `"name"`. Each of those fields must contain a Record with fields corresponding to the possible currencySign values: `"standard"` or `"accounting"`. The `"unit"` field (of [[LocaleData]][locale]) may have additional fields beyond the required field `"fallback"` with keys corresponding to core measurement unit identifiers corresponding to . Each field of `"unit"` must be a Record with fields corresponding to the possible unitDisplay values: `"narrow"`, `"short"`, and `"long"`.
+
All of the leaf fields so far described for the patterns tree (`"decimal"`, `"percent"`, great-grandchildren of `"currency"`, and grandchildren of `"unit"`) must be Records with fields corresponding to the possible signDisplay values: `"auto"`, `"always"`, `"never"`, and `"exceptZero"`. Each of these fields must be a Record with the keys `"standard"`, `"scientific"`, `"compactShort"`, and `"compactLong"`. Each of these fields must be a Record with the keys `"positivePattern"`, `"zeroPattern"`, and `"negativePattern"`.
+
The value of the aforementioned fields (the sign-dependent pattern fields) must be string values that must contain the substring `"{number}"` and may contain the substrings `"{plusSign}"`, `"{minusSign}"`, `"{compactSymbol}"`, `"{compactName}"`, `"{scientificSeparator}"`, and `"{scientificExponent}"`; the values within the `"percent"` field must also contain the substring `"{percentSign}"`; the values within the `"currency"` field must also contain one of the following substrings: `"{currencyCode}"`, `"{currencySymbol}"`, `"{currencyNarrowSymbol}"`, or `"{currencyName}"`; and the values within the `"unit"` field must also contain one of the following substrings: `"{unitSymbol}"`, `"{unitNarrowSymbol}"`, or `"{unitName}"`. The pattern strings must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
@@ -608,6 +807,11 @@
get Intl.NumberFormat.prototype.format
1. Set _nf_.[[BoundFormat]] to _F_.
1. Return _nf_.[[BoundFormat]].
+
+
+ The returned function is bound to _nf_ so that it can be passed directly to `Array.prototype.map` or other functions.
+ This is considered a historical artefact, as part of a convention which is no longer followed for new features, but is preserved to maintain compatibility with existing programs.
+
@@ -638,7 +842,7 @@
Intl.NumberFormat.prototype.resolvedOptions ()
1. If Type(_nf_) is not Object, throw a *TypeError* exception.
1. Let _nf_ be ? UnwrapNumberFormat(_nf_).
1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).
- 1. For each row of , except the header row, in any order, do
+ 1. For each row of , except the header row, in table order, do
1. Let _p_ be the Property value of the current row.
1. Let _v_ be the value of _nf_'s internal slot whose name is the Internal Slot value of the current row.
1. If _v_ is not *undefined*, then
@@ -675,6 +879,18 @@
Intl.NumberFormat.prototype.resolvedOptions ()
[[CurrencyDisplay]]
`"currencyDisplay"`
+
+
[[CurrencySign]]
+
`"currencySign"`
+
+
+
[[Unit]]
+
`"unit"`
+
+
+
[[UnitDisplay]]
+
`"unitDisplay"`
+
[[MinimumIntegerDigits]]
`"minimumIntegerDigits"`
@@ -699,6 +915,18 @@
Intl.NumberFormat.prototype.resolvedOptions ()
[[UseGrouping]]
`"useGrouping"`
+
+
[[Notation]]
+
`"notation"`
+
+
+
[[CompactDisplay]]
+
`"compactDisplay"`
+
+
+
[[SignDisplay]]
+
`"signDisplay"`
+
@@ -721,15 +949,22 @@
Properties of Intl.NumberFormat Instances
[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.
+
[[DataLocale]] is a String value with the language tag of the nearest locale for which the implementation has data to perform the formatting operation. It will be a parent locale of [[Locale]].
[[NumberingSystem]] is a String value with the "type" given in Unicode Technical Standard 35 for the numbering system used for formatting.
-
[[Style]] is one of the String values `"decimal"`, `"currency"`, or `"percent"`, identifying the number format style used.
-
[[Currency]] is a String value with the currency code identifying the currency to be used if formatting with the `"currency"` style. It is only used when [[Style]] has the value `"currency"`.
-
[[CurrencyDisplay]] is one of the String values `"code"`, `"symbol"`, or `"name"`, specifying whether to display the currency as an ISO 4217 alphabetic currency code, a localized currency symbol, or a localized currency name if formatting with the `"currency"` style. It is only used when [[Style]] has the value `"currency"`.
+
[[Style]] is one of the String values `"decimal"`, `"currency"`, `"percent"`, or `"unit"`, identifying the type of quantity being measured.
+
[[Currency]] is a String value with the currency code identifying the currency to be used if formatting with the `"currency"` unit type. It is only used when [[Style]] has the value `"currency"`.
+
[[CurrencyDisplay]] is one of the String values `"code"`, `"symbol"`, `"narrowSymbol"`, or `"name"`, specifying whether to display the currency as an ISO 4217 alphabetic currency code, a localized currency symbol, or a localized currency name if formatting with the `"currency"` style. It is only used when [[Style]] has the value `"currency"`.
+
[[CurrencySign]] is one of the String values `"standard"` or `"accounting"`, specifying whether to render negative numbers in accounting format, often signified by parenthesis. It is only used when [[Style]] has the value `"currency"` and when [[SignDisplay]] is not `"never"`.
+
[[Unit]] is a core unit identifier, as defined by Unicode Technical Standard #35, Part 2, Section 6. It is only used when [[Style]] has the value `"unit"`.
+
[[UnitDisplay]] is one of the String values `"short"`, `"narrow"`, or `"long"`, specifying whether to display the unit as a symbol, narrow symbol, or localized long name if formatting with the `"unit"` style. It is only used when [[Style]] has the value `"unit"`.
[[MinimumIntegerDigits]] is a non-negative integer Number value indicating the minimum integer digits to be used. Numbers will be padded with leading zeroes if necessary.
-
[[MinimumFractionDigits]] and [[MaximumFractionDigits]] are non-negative integer Number values indicating the minimum and maximum fraction digits to be used. Numbers will be rounded or padded with trailing zeroes if necessary.
-
[[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] are positive integer Number values indicating the minimum and maximum fraction digits to be shown. Either none or both of these properties are present; if they are, they override minimum and maximum integer and fraction digits – the formatter uses however many integer and fraction digits are required to display the specified number of significant digits.
+
[[MinimumFractionDigits]] and [[MaximumFractionDigits]] are non-negative integer Number values indicating the minimum and maximum fraction digits to be used. Numbers will be rounded or padded with trailing zeroes if necessary. These properties are only used when [[RoundingType]] is `"fractionDigits"`.
+
[[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] are positive integer Number values indicating the minimum and maximum fraction digits to be shown. If present, the formatter uses however many fraction digits are required to display the specified number of significant digits. These properties are only used when [[RoundingType]] is `"significantDigits"`.
[[UseGrouping]] is a Boolean value indicating whether a grouping separator should be used.
-
[[PositivePattern]] and [[NegativePattern]] are String values as described in .
+
[[RoundingType]] is one of the String values `"fractionDigits"`, `"significantDigits"`, or `"compactRounding"`, indicating which rounding strategy to use. If `"fractionDigits"`, the number is rounded according to [[MinimumFractionDigits]] and [[MaximumFractionDigits]], as described above. If `"significantDigits"`, the number is rounded according to [[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] as described above. If `"compactRounding"`, the number is rounded to 1 maximum fraction digit if there is 1 digit before the decimal separator, and otherwise round to 0 fraction digits.
+
[[Notation]] is one of the String values `"standard"`, `"scientific"`, `"engineering"`, or `"compact"`, specifying whether the number should be displayed without scaling, scaled to the units place with the power of ten in scientific notation, scaled to the nearest thousand with the power of ten in scientific notation, or scaled to the nearest locale-dependent compact decimal notation power of ten with the corresponding compact decimal notation affix.
+
[[CompactDisplay]] is one of the String values `"short"` or `"long"`, specifying whether to display compact notation affixes in short form ("5K") or long form ("5 thousand") if formatting with the `"compact"` notation. It is only used when [[Notation]] has the value `"compact"`.
+
[[SignDisplay]] is one of the String values `"auto"`, `"always"`, `"never"`, or `"exceptZero"`, specifying whether to show the sign on negative numbers only, positive and negative numbers including zero, neither positive nor negative numbers, or positive and negative numbers but not zero.
diff --git a/section11/numberformat_proposed_out.html b/section11/numberformat_proposed_out.html
new file mode 100644
index 0000000..69b9280
--- /dev/null
+++ b/section11/numberformat_proposed_out.html
@@ -0,0 +1,2404 @@
+
+
+ The abstract operation InitializeNumberFormat accepts the arguments numberFormat (which must be an object), locales, and options. It initializes numberFormat as a NumberFormat object. The following steps are taken:
+
+
+
+
Let requestedLocales be ? CanonicalizeLocaleList(locales).
Let compactDisplay be ? GetOption(options, "compactDisplay", "string", « "short", "long" », "short").
If notation is "compact", then
Set numberFormat.[[CompactDisplay]] to compactDisplay.
Let useGrouping be ? GetOption(options, "useGrouping", "boolean", undefined, true).
Set numberFormat.[[UseGrouping]] to useGrouping.
Let signDisplay be ? GetOption(options, "signDisplay", "string", « "auto", "never", "always", "exceptZero" », "auto").
Set numberFormat.[[SignDisplay]] to signDisplay.
Return numberFormat.
+
+
+
+
+
1.1.3CurrencyDigits ( currency )
+
+
+ When the abstract operation CurrencyDigits is called with an argument currency (which must be an upper case String value), the following steps are taken:
+
+
+
+
If the ISO 4217 currency and funds code list contains currency as an alphabetic code, return the minor unit value corresponding to the currency from the list; otherwise, return 2.
+
+
+
+
+
1.1.4Number Format Functions
+
+
A Number format function is an anonymous built-in function that has a [[NumberFormat]] internal slot.
+
When a Number format function F is called with optional argument value, the following steps are taken:
+
+
Let nf be F.[[NumberFormat]].
Assert: Type(nf) is Object and nf has an [[InitializedNumberFormat]] internal slot.
+ The length property of a Number format function is 1.
+
+
+
+
+
+
1.1.5FormatNumberToString ( intlObject, x )
+
+
+ The FormatNumberToString abstract operation is called with arguments intlObject (which must be an object with [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], and [[MaximumFractionDigits]] internal slots), and x (which must be a Number value), and returns a Record containing two values: x as a string value with digits formatted according to the five formatting parameters in the field [[FormattedString]], and the final floating decimal value of x after rounding has been performed in the field [[RoundedNumber]].
+
+
+
+
Let isNegative be x < 0 or x is -0.
If isNegative, then
Let x be -x.
If intlObject.[[RoundingType]] is "significantDigits", then
Let result be ToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]]).
Else If intlObject.[[RoundingType]] is "fractionDigits", then,
Let result be ToRawFixed(x, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]]).
Else,
Assert: intlObject.[[RoundingType]] is "compactRounding".
Let minInteger be intlObject.[[MinimumIntegerDigits]].
If int < minInteger, then
Let forwardZeros be the String consisting of minInteger–int occurrences of the character "0".
Let string be the concatenation of Strings forwardZeros and string.
If isNegative, then
Let x be -x.
Return the Record { [[RoundedNumber]]: x, [[FormattedString]]: string }.
+
+
+
+
+
1.1.6PartitionNumberPattern ( numberFormat, x )
+
+
+ The PartitionNumberPattern abstract operation is called with arguments numberFormat (which must be an object initialized as a NumberFormat) and x (which must be a Number value), interprets x as a numeric value, and creates the corresponding parts according to the effective locale and the formatting options of numberFormat. The following steps are taken:
+
+
+
+
Let exponent be 0.
If x is NaN, then
Let n be an implementation- and locale-dependent (ILD) String value indicating the NaN value.
Else if x is not a finite Number,
Let n be an ILD String value indicating infinity.
Else,
If numberFormat.[[Style]] is "percent", let x be 100 × x.
Let beginIndex be Call(%StringProto_indexOf%, pattern, « "{", 0 »).
Let endIndex be 0.
Let nextIndex be 0.
Let length be the number of code units in pattern.
Repeat, while beginIndex is an integer index into pattern
Set endIndex to Call(%StringProto_indexOf%, pattern, « "}", beginIndex »).
Assert: endIndex is greater than beginIndex.
If beginIndex is greater than nextIndex, then
Let literal be a substring of pattern from position nextIndex, inclusive, to position beginIndex, exclusive.
Append a new Record { [[Type]]: "literal", [[Value]]: literal } as the last element of result.
Let p be the substring of pattern from position beginIndex, exclusive, to position endIndex, exclusive.
If p is equal to "number", then
If x is NaN, then
Append a new Record { [[Type]]: "nan", [[Value]]: n } as the last element of result.
Else if x is not a finite Number,
Append a new Record { [[Type]]: "infinity", [[Value]]: n } as the last element of result.
Else,
If the numberFormat.[[NumberingSystem]] matches one of the values in the "Numbering System" column of Table 1 below, then
Let digits be a List whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the "Digits" column of the matching row in Table 1.
Replace each digit in n with the value of digits[digit].
Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
Let decimalSepIndex be Call(%StringProto_indexOf%, n, « ".", 0 »).
If decimalSepIndex > 0, then
Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive.
Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.
Else,
Let integer be n.
Let fraction be undefined.
If the numberFormat.[[UseGrouping]] is true, then
Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer.
Assert: The number of elements in groupsList is greater than 0.
Append a new Record { [[Type]]: "group", [[Value]]: groupSepSymbol } as the last element of result.
Else,
Append a new Record { [[Type]]: "integer", [[Value]]: integer } as the last element of result.
If fraction is not undefined, then
Let decimalSepSymbol be the ILND String representing the decimal separator.
Append a new Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } as the last element of result.
Append a new Record { [[Type]]: "fraction", [[Value]]: fraction } as the last element of result.
Else if p is equal to "plusSign", then
Let plusSignSymbol be the ILND String representing the plus sign.
Append a new Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } as the last element of result.
Else if p is equal to "minusSign", then
Let minusSignSymbol be the ILND String representing the minus sign.
Append a new Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } as the last element of result.
Else if p is equal to "compactSymbol", then
Let compactSymbol be an ILD string representing exponent in short form, which may depend on x in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a "{compactSymbol}" placeholder.
Append a new Record { [[Type]]: "compact", [[Value]]: compactSymbol } as the last element of result.
Else if p is equal to "compactName", then
Let compactName be an ILD string representing exponent in long form, which may depend on x in languages having different plural forms. The implementation must be able to provide this string, or else the pattern would not have a "{compactName}" placeholder.
Append a new Record { [[Type]]: "compact", [[Value]]: compactName } as the last element of result.
Else if p is equal to "scientificSeparator", then
Let scientificSeparator be the ILND String representing the exponent separator.
Append a new Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } as the last element of result.
Else if p is equal to "scientificExponent", then
If exponent < 0, then
Let minusSignSymbol be the ILND String representing the minus sign.
Append a new Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } as the last element of result.
Let exponent be -exponent.
Let exponentResult be ToRawFixed(exponent, 1, 0, 0).
Append a new Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } as the last element of result.
Else if p is equal to "percentSign", then
Let percentSignSymbol be the ILND String representing the percent sign.
Append a new Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } as the last element of result.
Else if p is equal to "unitSymbol" and numberFormat.[[Style]] is "unit" or "percent", then
Let unit be numberFormat.[[Unit]].
Let mu be an ILD string representing unit in short form, which may depend on x in languages having different plural forms.
Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result.
Else if p is equal to "unitNarrowSymbol" and numberFormat.[[Style]] is "unit" or "percent", then
Let unit be numberFormat.[[Unit]].
Let mu be an ILD string representing unit in narrow form, which may depend on x in languages having different plural forms.
Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result.
Else if p is equal to "unitName" and numberFormat.[[Style]] is "unit" or "percent", then
Let unit be numberFormat.[[Unit]].
Let mu be an ILD string representing unit in long form, which may depend on x in languages having different plural forms.
Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result.
Else if p is equal to "currencyCode" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be currency.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencySymbol" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencyNarrowSymbol" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be an ILD string representing currency in narrow form. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else if p is equal to "currencyName" and numberFormat.[[Style]] is "currency", then
Let currency be numberFormat.[[Currency]].
Let cd be an ILD string representing currency in long form, which may depend on x in languages having different plural forms. If the implementation does not have such a representation of currency, use currency itself.
Append a new Record { [[Type]]: "currency", [[Value]]: cd } as the last element of result.
Else,
Let unknown be an ILND String based on x and p.
Append a new Record { [[Type]]: "unknown", [[Value]]: unknown } as the last element of result.
Set nextIndex to endIndex + 1.
Set beginIndex to Call(%StringProto_indexOf%, pattern, « "{", nextIndex »).
If nextIndex is less than length, then
Let literal be the substring of pattern from position nextIndex, inclusive, to position length, exclusive.
Append a new Record { [[Type]]: "literal", [[Value]]: literal } as the last element of result.
Return result.
+
+
+
Table 1: Numbering systems with simple digit mappings
+
+
+ The computations rely on String values and locations within numeric strings that are dependent upon the implementation and the effective locale of numberFormat ("ILD") or upon the implementation, the effective locale, and the numbering system of numberFormat ("ILND"). The ILD and ILND Strings mentioned, other than those for currency names, must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
+
+
+ Note 2
+ It is recommended that implementations use the locale provided by the Common Locale Data Repository (available at http://cldr.unicode.org/).
+
+
+
+
+
+
1.1.7FormatNumber( numberFormat, x )
+
+
+ The FormatNumber abstract operation is called with arguments numberFormat (which must be an object initialized as a NumberFormat) and x (which must be a Number value), and performs the following steps:
+
+
Set result to a String value produced by concatenating result and part.[[Value]].
Return result.
+
+
+
+
+
1.1.8FormatNumberToParts( numberFormat, x )
+
+
+ The FormatNumberToParts abstract operation is called with arguments numberFormat (which must be an object initialized as a NumberFormat) and x (which must be a Number value), and performs the following steps:
+
+
+ When the ToRawPrecision abstract operation is called with arguments x (which must be a finite non-negative number), minPrecision, and maxPrecision (both must be integers between 1 and 21), the following steps are taken:
+
+
+
+
Let p be maxPrecision.
If x = 0, then
Let m be the String consisting of p occurrences of the character "0".
Let e be 0.
Let xFinal be 0.
Else,
Let e be the base 10 logarithm of x rounded down to the nearest integer.
Let n be an integer such that 10p–1 ≤ n < 10p and for which the exact mathematical value of n × 10e–p+1 – x is as close to zero as possible. If there is more than one such n, pick the one for which n × 10e–p+1 is larger.
Let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
Let xFinal be n × 10e–p+1.
If e ≥ p–1, then
Let m be the concatenation of m and e–p+1 occurrences of the character "0".
Let int be e+1.
Else If e ≥ 0, then
Let m be the concatenation of the first e+1 characters of m, the character ".", and the remaining p–(e+1) characters of m.
Let int be e+1.
Else,
Assert: e < 0.
Let m be the concatenation of the String "0.", –(e+1) occurrences of the character "0", and the string m.
Let int be 1.
If m contains the character ".", and maxPrecision > minPrecision, then
Let cut be maxPrecision – minPrecision.
Repeat, while cut > 0 and the last character of m is "0"
Remove the last character from m.
Decrease cut by 1.
If the last character of m is ".", then
Remove the last character from m.
Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int }.
+
+ When the ToRawFixed abstract operation is called with arguments x (which must be a finite non-negative number), minInteger (which must be an integer between 1 and 21), minFraction, and maxFraction (which must be integers between 0 and 20), the following steps are taken:
+
+
+
+
Let f be maxFraction.
Let n be an integer for which the exact mathematical value of n ÷ 10f – x is as close to zero as possible. If there are two such n, pick the larger n.
Let xFinal be n ÷ 10f.
If n = 0, let m be the String "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
If f ≠ 0, then
Let k be the number of characters in m.
If k ≤ f, then
Let z be the String consisting of f+1–k occurrences of the character "0".
Let m be the concatenation of Strings z and m.
Let k be f+1.
Let a be the first k–f characters of m, and let b be the remaining f characters of m.
Let m be the concatenation of the three Strings a, ".", and b.
Let int be the number of characters in a.
Else, let int be the number of characters in m.
Let cut be maxFraction – minFraction.
Repeat, while cut > 0 and the last character of m is "0"
Remove the last character from m.
Decrease cut by 1.
If the last character of m is ".", then
Remove the last character from m.
Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int }.
+
+
+
+
+
1.1.11UnwrapNumberFormat( nf )
+
+ The UnwrapNumberFormat abstract operation gets the underlying NumberFormat operation
+ for various methods which implement ECMA-402 v1 semantics for supporting initializing
+ existing Intl objects.
+
+
+ The abstract operation GetNumberFormatPattern considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted and returns a pattern, a String value as described in 1.3.3.
+
+
Let currencyDisplay be numberFormat.[[CurrencyDisplay]].
Let currencySign be numberFormat.[[CurrencySign]].
Let patterns be patterns.[["currency"]].
If patterns.[[<currency>]] is undefined, then
Let currency be "fallback".
Let patterns be patterns.[[<currency>]].
Let patterns be patterns.[[<currencyDisplay>]].
Let patterns be patterns.[[<currencySign>]].
Else,
Assert: style is "decimal".
Let patterns be patterns.[["decimal"]].
Let signDisplay be numberFormat.[[SignDisplay]].
Let patterns be patterns.[[<signDisplay>]].
Let notation be numberFormat.[[Notation]].
Let displayNotation be "standard".
If notation is "scientific" or notation is "engineering", then
Let displayNotation be "scientific".
Else If exponent is not 0, then
Assert: notation is "compact".
Let compactDisplay be numberFormat.[[CompactDisplay]].
If compactDisplay is "short", then
Let displayNotation be "compactShort".
Else,
Assert: compactDisplay is "long".
Let displayNotation be "compactLong".
Let patterns be patterns.[[<displayNotation>]].
If x is not NaN and x < 0 or x is -0, then
Let pattern be patterns.[[negativePattern]].
Else If x is 0, then
Let pattern be patterns.[[zeroPattern]].
Else,
Let pattern be patterns.[[positivePattern]].
Return pattern.
+
+
+
+
+
1.1.14ComputeExponent ( numberFormat, x )
+
+ The abstract operation ComputeExponent computes an exponent (power of ten) by which to scale x according to the number formatting settings. It handles cases such as 999 rounding up to 1000, requiring a different exponent.
+
+
+
If x = 0, then
Return 0.
If x < 0, then
Let x = -x.
Let magnitude be the base 10 logarithm of x rounded down to the nearest integer.
+ The abstract operation ComputeExponentHelper computes an exponent by which to scale a number of the given magnitude (power of ten of the most significant digit) according to the locale and the desired notation (scientific, engineering, or compact).
+
+
+
Let notation be numberFormat.[[Notation]].
If notation is "standard", then
Return 0.
Else If notation is "scientific", then
Return magnitude.
Else If notation is "engineering", then
Let thousands be the greatest integer that is not greater than magnitude ÷ 3.
Return thousands × 3.
Else,
Assert: notation is "compact".
Let exponent be an implementation-dependent integer by which to scale a number of the given magnitude in compact notation for the current locale.
Return exponent.
+
+
+
+
+
+
1.2The Intl.NumberFormat Constructor
+
+
+ The NumberFormat constructor is the %NumberFormat% intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in .
+
+
+ The value of the length property of the supportedLocalesOf method is 1.
+
+
+
+
+
+
1.3.3Internal slots
+
+
+ The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in .
+
+
+
+
+ The value of the [[RelevantExtensionKeys]] internal slot is « "nu" ».
+
+
+
+ Note 1
+ Unicode Technical Standard 35 describes two locale extension keys that are relevant to number formatting, "nu" for numbering system and "cu" for currency. Intl.NumberFormat, however, requires that the currency of a currency format is specified through the currency property in the options objects.
+
+
+
+
+ The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in and the following additional constraints:
+
+
+
+
+
The list that is the value of the "nu" field of any locale field of [[LocaleData]] must not include the values "native", "traditio", or "finance".
+
[[LocaleData]][locale] must have a patterns field for all locale values. The value of this field must be a Record, which must have three fields: "decimal", "currency", and "unit".
+
The two fields "currency" and "unit" noted above must be Records with at least one field, "fallback". The "currency" may have additional fields with keys corresponding to currency codes according to . Each field of "currency" must be a Record with fields corresponding to the possible currencyDisplay values: "code", "symbol", "narrowSymbol", and "name". Each of those fields must contain a Record with fields corresponding to the possible currencySign values: "standard" or "accounting". The "unit" field (of [[LocaleData]][locale]) may have additional fields beyond the required field "fallback" with keys corresponding to core measurement unit identifiers corresponding to . Each field of "unit" must be a Record with fields corresponding to the possible unitDisplay values: "narrow", "short", and "long".
+
All of the leaf fields so far described for the patterns tree ("decimal", great-grandchildren of "currency", and grandchildren of "unit") must be Records with fields corresponding to the possible signDisplay values: "auto", "always", "never", and "exceptZero". Each of these fields must be a Record with the keys "standard", "scientific", "compactShort", and "compactLong". Each of these fields must be a Record with the keys "positivePattern", "zeroPattern", and "negativePattern".
+
The value of the aforementioned fields (the sign-dependent pattern fields) must be string values that must contain the substring "{number}" and may contain the substrings "{plusSign}", "{minusSign}", "{compactSymbol}", "{compactName}", "{scientificSeparator}", and "{scientificExponent}"; the values within the "currency" field must also contain one of the following substrings: "{currencyCode}", "{currencySymbol}", "{currencyNarrowSymbol}", or "{currencyName}"; and the values within the "unit" field must also contain one of the following substrings: "{percentSign}", "{unitSymbol}", "{unitNarrowSymbol}", or "{unitName}". The pattern strings must not contain any characters in the General Category "Number, decimal digit" as specified by the Unicode Standard.
+
+
+ Note 2
+ It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at http://cldr.unicode.org/).
+
+
+
+
+
+
+
1.4Properties of the Intl.NumberFormat Prototype Object
+
+
+ The Intl.NumberFormat prototype object is itself an ordinary object. %NumberFormatPrototype% is not an Intl.NumberFormat instance and does not have an [[InitializedNumberFormat]] internal slot or any of the other internal slots of Intl.NumberFormat instance objects.
+
+
+
+
+
1.4.1Intl.NumberFormat.prototype.constructor
+
+
+ The initial value of Intl.NumberFormat.prototype.constructor is the intrinsic object %NumberFormat%.
+
+
+ The initial value of the @@toStringTag property is the string value "Object".
+
+
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+
+
+
+
+
+
1.4.3get Intl.NumberFormat.prototype.format
+
+
+ Intl.NumberFormat.prototype.format is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:
+
+
+
+
Let nf be the this value.
If Type(nf) is not Object, throw a TypeError exception.
Let F be a new built-in function object as defined in Number Format Functions (1.1.4).
Set F.[[NumberFormat]] to nf.
Set nf.[[BoundFormat]] to F.
Return nf.[[BoundFormat]].
+
+
+ Note
+ The returned function is bound to nf so that it can be passed directly to Array.prototype.map or other functions.
+ This is considered a historical artefact, as part of a convention which is no longer followed for new features, but is preserved to maintain compatibility with existing programs.
+
+
+
+
+
+
1.4.4Intl.NumberFormat.prototype.formatToParts ( value )
+
+
+ When the formatToParts method is called with an optional argument value, the following steps are taken:
+
+
+
+
Let nf be the this value.
If Type(nf) is not Object, throw a TypeError exception.
If nf does not have an [[InitializedNumberFormat]] internal slot, throw a TypeError exception.
+ Intl.NumberFormat instances have an [[InitializedNumberFormat]] internal slot.
+
+
+
+
+ Intl.NumberFormat instances also have several internal slots that are computed by the constructor:
+
+
+
+
+
[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.
+
[[DataLocale]] is a String value with the language tag of the nearest locale for which the implementation has data to perform the formatting operation. It will be a parent locale of [[Locale]].
+
[[NumberingSystem]] is a String value with the "type" given in Unicode Technical Standard 35 for the numbering system used for formatting.
+
[[Style]] is one of the String values "decimal", "currency", "percent", or "unit", identifying the type of quantity being measured.
+
[[Currency]] is a String value with the currency code identifying the currency to be used if formatting with the "currency" unit type. It is only used when [[Style]] has the value "currency".
+
[[CurrencyDisplay]] is one of the String values "code", "symbol", "narrowSymbol", or "name", specifying whether to display the currency as an ISO 4217 alphabetic currency code, a localized currency symbol, or a localized currency name if formatting with the "currency" style. It is only used when [[Style]] has the value "currency".
+
[[CurrencySign]] is one of the String values "standard" or "accounting", specifying whether to render negative numbers in accounting format, often signified by parenthesis. It is only used when [[Style]] has the value "currency" and when [[SignDisplay]] is not "never".
+
[[Unit]] is a core unit identifier, as defined by Unicode Technical Standard #35, Part 2, Section 6. It is only used when [[Style]] has the value "unit" or "percent".
+
[[UnitDisplay]] is one of the String values "short", "narrow", or "long", specifying whether to display the unit as a symbol, narrow symbol, or localized long name if formatting with the "unit" or "percent" style. It is only used when [[Style]] has the value "unit" or "percent".
+
[[MinimumIntegerDigits]] is a non-negative integer Number value indicating the minimum integer digits to be used. Numbers will be padded with leading zeroes if necessary.
+
[[MinimumFractionDigits]] and [[MaximumFractionDigits]] are non-negative integer Number values indicating the minimum and maximum fraction digits to be used. Numbers will be rounded or padded with trailing zeroes if necessary. These properties are only used when [[RoundingType]] is "fractionDigits".
+
[[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] are positive integer Number values indicating the minimum and maximum fraction digits to be shown. If present, the formatter uses however many fraction digits are required to display the specified number of significant digits. These properties are only used when [[RoundingType]] is "significantDigits".
+
[[UseGrouping]] is a Boolean value indicating whether a grouping separator should be used.
+
[[RoundingType]] is one of the String values "fractionDigits", "significantDigits", or "compactRounding", indicating which rounding strategy to use. If "fractionDigits", the number is rounded according to [[MinimumFractionDigits]] and [[MaximumFractionDigits]], as described above. If "significantDigits", the number is rounded according to [[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] as described above. If "compactRounding", the number is rounded to 1 maximum fraction digit if there is 1 digit before the decimal separator, and otherwise round to 0 fraction digits.
+
[[Notation]] is one of the String values "standard", "scientific", "engineering", or "compact", specifying whether the number should be displayed without scaling, scaled to the units place with the power of ten in scientific notation, scaled to the nearest thousand with the power of ten in scientific notation, or scaled to the nearest locale-dependent compact decimal notation power of ten with the corresponding compact decimal notation affix.
+
[[CompactDisplay]] is one of the String values "short" or "long", specifying whether to display compact notation affixes in short form ("5K") or long form ("5 thousand") if formatting with the "compact" notation. It is only used when [[Notation]] has the value "compact".
+
[[SignDisplay]] is one of the String values "auto", "always", "never", or "exceptZero", specifying whether to show the sign on negative numbers only, positive and negative numbers including zero, neither positive nor negative numbers, or positive and negative numbers but not zero.
+
+
+
+ Finally, Intl.NumberFormat instances have a [[BoundFormat]] internal slot that caches the function returned by the format accessor (1.4.3).
+
+
+
+
+
\ No newline at end of file
diff --git a/section6/locales-currencies-tz_current.html b/section6/locales-currencies-tz_current.html
new file mode 100644
index 0000000..4331e7c
--- /dev/null
+++ b/section6/locales-currencies-tz_current.html
@@ -0,0 +1,160 @@
+
+
Identification of Locales, Currencies, and Time Zones
+
+
+ This clause describes the String values used in the ECMAScript 2019 Internationalization API Specification to identify locales, currencies, and time zones.
+
+
+
+
Case Sensitivity and Case Mapping
+
+
+ The String values used to identify locales, currencies, and time zones are interpreted in a case-insensitive manner, treating the Unicode Basic Latin characters `"A"` to `"Z"` (U+0041 to U+005A) as equivalent to the corresponding Basic Latin characters `"a"` to `"z"` (U+0061 to U+007A). No other case folding equivalences are applied. When mapping to upper case, a mapping shall be used that maps characters in the range `"a"` to `"z"` (U+0061 to U+007A) to the corresponding characters in the range `"A"` to `"Z"` (U+0041 to U+005A) and maps no other characters to the latter range.
+
+
+
+ EXAMPLES `"ß"` (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).
+
+
+
+
+
Language Tags
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies locales using language tags as defined by IETF BCP 47 (RFCs 5646 and 4647 or their successors), which may include extensions such as those registered through RFC 6067. Their canonical form is specified in RFC 5646 section 4.5 or its successor.
+
+
+
+ BCP 47 language tags that meet those validity criteria of RFC 5646 section 2.2.9 that can be verified without reference to the IANA Language Subtag Registry are considered structurally valid. All structurally valid language tags are valid for use with the APIs defined by this standard. However, the set of locales and thus language tags that an implementation supports with adequate localizations is implementation dependent. The constructors Collator, NumberFormat, DateTimeFormat, and PluralRules map the language tags used in requests to locales supported by their respective implementations.
+
+
+
+
+
Unicode Locale Extension Sequences
+
+
+ This standard uses the term `"Unicode locale extension sequence"` for any substring of a language tag that is not part of a private use subtag sequence, starts with a separator `"-"` and the singleton `"u"`, and includes the maximum sequence of following non-singleton subtags and their preceding `"-"` separators.
+
+
+
+
+
IsStructurallyValidLanguageTag ( _locale_ )
+
+
+ The IsStructurallyValidLanguageTag abstract operation verifies that the _locale_ argument (which must be a String value)
+
+
+
+
represents a well-formed BCP 47 language tag as specified in RFC 5646 section 2.1, or successor,
+
does not include duplicate variant subtags, and
+
does not include duplicate singleton subtags.
+
+
+
+ The abstract operation returns true if _locale_ can be generated from the ABNF grammar in section 2.1 of the RFC, starting with Language-Tag, and does not contain duplicate variant or singleton subtags (other than as a private use subtag). It returns false otherwise. Terminal value characters in the grammar are interpreted as the Unicode equivalents of the ASCII octet values given.
+
+
+
+
+
CanonicalizeLanguageTag ( _locale_ )
+
+
+ The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized form of the _locale_ argument (which must be a String value that is a structurally valid BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation).
+ A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or successor, to bring the language tag into canonical form, and to regularize the case of the subtags. Furthermore, a conforming implementation shall not take the steps to bring a language tag into `"extlang form"`, nor shall it reorder variant subtags.
+
+
+
+ The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include canonicalization rules for the extension subtag sequences they define that go beyond the canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not required, to apply these additional rules.
+
+
+
+
+
DefaultLocale ()
+
+
+ The DefaultLocale abstract operation returns a String value representing the structurally valid () and canonicalized () BCP 47 language tag for the host environment's current locale.
+
+
+
+
+
+
+
Currency Codes
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies currencies using 3-letter currency codes as defined by ISO 4217. Their canonical form is upper case.
+
+
+
+ All well-formed 3-letter ISO 4217 currency codes are allowed. However, the set of combinations of currency code and language tag for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, the ISO 4217 currency code is used for formatting.
+
+
+
+
IsWellFormedCurrencyCode ( _currency_ )
+
+
+ The IsWellFormedCurrencyCode abstract operation verifies that the _currency_ argument (which must be a String value) represents a well-formed 3-letter ISO currency code. The following steps are taken:
+
+
+
+ 1. Let _normalized_ be the result of mapping _currency_ to upper case as described in .
+ 1. If the number of elements in _normalized_ is not 3, return *false*.
+ 1. If _normalized_ contains any character that is not in the range `"A"` to `"Z"` (U+0041 to U+005A), return *false*.
+ 1. Return *true*.
+
+
+
+
+
+
+
Time Zone Names
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies time zones using the Zone and Link names of the IANA Time Zone Database. Their canonical form is the corresponding Zone name in the casing used in the IANA Time Zone Database.
+
+
+
+ All registered Zone and Link names are allowed. Implementations must recognize all such names, and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.
+
+
+
+
IsValidTimeZoneName ( _timeZone_ )
+
+
+ The IsValidTimeZoneName abstract operation verifies that the _timeZone_ argument (which must be a String value) represents a valid Zone or Link name of the IANA Time Zone Database.
+
+
+ The abstract operation returns true if _timeZone_, converted to upper case as described in , is equal to one of the Zone or Link names of the IANA Time Zone Database, converted to upper case as described in . It returns false otherwise.
+
+
+
+
+
CanonicalizeTimeZoneName
+
+
+ The CanonicalizeTimeZoneName abstract operation returns the canonical and case-regularized form of the _timeZone_ argument (which must be a String value that is a valid time zone name as verified by the IsValidTimeZoneName abstract operation). The following steps are taken:
+
+
+
+ 1. Let _ianaTimeZone_ be the Zone or Link name of the IANA Time Zone Database such that _timeZone_, converted to upper case as described in , is equal to _ianaTimeZone_, converted to upper case as described in .
+ 1. If _ianaTimeZone_ is a Link name, let _ianaTimeZone_ be the corresponding Zone name as specified in the `"backward"` file of the IANA Time Zone Database.
+ 1. If _ianaTimeZone_ is `"Etc/UTC"` or `"Etc/GMT"`, return `"UTC"`.
+ 1. Return _ianaTimeZone_.
+
+
+
+ The Intl.DateTimeFormat constructor allows this time zone name; if the time zone is not specified, the host environment's current time zone is used. Implementations shall support UTC and the host environment's current time zone (if different from UTC) in formatting.
+
+
+
+
+
DefaultTimeZone ()
+
+
+ The DefaultTimeZone abstract operation returns a String value representing the valid () and canonicalized () time zone name for the host environment's current time zone.
+
Identification of Locales, Currencies, and Time Zones, and Measurement Units
+
+
+ This clause describes the String values used in the ECMAScript 2019 Internationalization API Specification to identify locales, currencies, time zones, and measurement units.
+
+
+
+
Case Sensitivity and Case Mapping
+
+
+ The String values used to identify locales, currencies, and time zones are interpreted in a case-insensitive manner, treating the Unicode Basic Latin characters `"A"` to `"Z"` (U+0041 to U+005A) as equivalent to the corresponding Basic Latin characters `"a"` to `"z"` (U+0061 to U+007A). No other case folding equivalences are applied. When mapping to upper case, a mapping shall be used that maps characters in the range `"a"` to `"z"` (U+0061 to U+007A) to the corresponding characters in the range `"A"` to `"Z"` (U+0041 to U+005A) and maps no other characters to the latter range.
+
+
+
+ EXAMPLES `"ß"` (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).
+
+
+
+
+
Language Tags
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies locales using language tags as defined by IETF BCP 47 (RFCs 5646 and 4647 or their successors), which may include extensions such as those registered through RFC 6067. Their canonical form is specified in RFC 5646 section 4.5 or its successor.
+
+
+
+ BCP 47 language tags that meet those validity criteria of RFC 5646 section 2.2.9 that can be verified without reference to the IANA Language Subtag Registry are considered structurally valid. All structurally valid language tags are valid for use with the APIs defined by this standard. However, the set of locales and thus language tags that an implementation supports with adequate localizations is implementation dependent. The constructors Collator, NumberFormat, DateTimeFormat, and PluralRules map the language tags used in requests to locales supported by their respective implementations.
+
+
+
+
+
Unicode Locale Extension Sequences
+
+
+ This standard uses the term `"Unicode locale extension sequence"` for any substring of a language tag that is not part of a private use subtag sequence, starts with a separator `"-"` and the singleton `"u"`, and includes the maximum sequence of following non-singleton subtags and their preceding `"-"` separators.
+
+
+
+
+
IsStructurallyValidLanguageTag ( _locale_ )
+
+
+ The IsStructurallyValidLanguageTag abstract operation verifies that the _locale_ argument (which must be a String value)
+
+
+
+
represents a well-formed BCP 47 language tag as specified in RFC 5646 section 2.1, or successor,
+
does not include duplicate variant subtags, and
+
does not include duplicate singleton subtags.
+
+
+
+ The abstract operation returns true if _locale_ can be generated from the ABNF grammar in section 2.1 of the RFC, starting with Language-Tag, and does not contain duplicate variant or singleton subtags (other than as a private use subtag). It returns false otherwise. Terminal value characters in the grammar are interpreted as the Unicode equivalents of the ASCII octet values given.
+
+
+
+
+
CanonicalizeLanguageTag ( _locale_ )
+
+
+ The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized form of the _locale_ argument (which must be a String value that is a structurally valid BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation).
+ A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or successor, to bring the language tag into canonical form, and to regularize the case of the subtags. Furthermore, a conforming implementation shall not take the steps to bring a language tag into `"extlang form"`, nor shall it reorder variant subtags.
+
+
+
+ The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include canonicalization rules for the extension subtag sequences they define that go beyond the canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not required, to apply these additional rules.
+
+
+
+
+
DefaultLocale ()
+
+
+ The DefaultLocale abstract operation returns a String value representing the structurally valid () and canonicalized () BCP 47 language tag for the host environment's current locale.
+
+
+
+
+
+
+
Currency Codes
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies currencies using 3-letter currency codes as defined by ISO 4217. Their canonical form is upper case.
+
+
+
+ All well-formed 3-letter ISO 4217 currency codes are allowed. However, the set of combinations of currency code and language tag for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, the ISO 4217 currency code is used for formatting.
+
+
+
+
IsWellFormedCurrencyCode ( _currency_ )
+
+
+ The IsWellFormedCurrencyCode abstract operation verifies that the _currency_ argument (which must be a String value) represents a well-formed 3-letter ISO currency code. The following steps are taken:
+
+
+
+ 1. Let _normalized_ be the result of mapping _currency_ to upper case as described in .
+ 1. If the number of elements in _normalized_ is not 3, return *false*.
+ 1. If _normalized_ contains any character that is not in the range `"A"` to `"Z"` (U+0041 to U+005A), return *false*.
+ 1. Return *true*.
+
+
+
+
+
+
+
Time Zone Names
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies time zones using the Zone and Link names of the IANA Time Zone Database. Their canonical form is the corresponding Zone name in the casing used in the IANA Time Zone Database.
+
+
+
+ All registered Zone and Link names are allowed. Implementations must recognize all such names, and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.
+
+
+
+
IsValidTimeZoneName ( _timeZone_ )
+
+
+ The IsValidTimeZoneName abstract operation verifies that the _timeZone_ argument (which must be a String value) represents a valid Zone or Link name of the IANA Time Zone Database.
+
+
+ The abstract operation returns true if _timeZone_, converted to upper case as described in , is equal to one of the Zone or Link names of the IANA Time Zone Database, converted to upper case as described in . It returns false otherwise.
+
+
+
+
+
CanonicalizeTimeZoneName
+
+
+ The CanonicalizeTimeZoneName abstract operation returns the canonical and case-regularized form of the _timeZone_ argument (which must be a String value that is a valid time zone name as verified by the IsValidTimeZoneName abstract operation). The following steps are taken:
+
+
+
+ 1. Let _ianaTimeZone_ be the Zone or Link name of the IANA Time Zone Database such that _timeZone_, converted to upper case as described in , is equal to _ianaTimeZone_, converted to upper case as described in .
+ 1. If _ianaTimeZone_ is a Link name, let _ianaTimeZone_ be the corresponding Zone name as specified in the `"backward"` file of the IANA Time Zone Database.
+ 1. If _ianaTimeZone_ is `"Etc/UTC"` or `"Etc/GMT"`, return `"UTC"`.
+ 1. Return _ianaTimeZone_.
+
+
+
+ The Intl.DateTimeFormat constructor allows this time zone name; if the time zone is not specified, the host environment's current time zone is used. Implementations shall support UTC and the host environment's current time zone (if different from UTC) in formatting.
+
+
+
+
+
DefaultTimeZone ()
+
+
+ The DefaultTimeZone abstract operation returns a String value representing the valid () and canonicalized () time zone name for the host environment's current time zone.
+
+
+
+
+
+
+
+
+
Measurement Unit Identifiers
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies measurement units using a core unit identifier as defined by Unicode Technical Standard #35, Part 2, Section 6. Their canonical form is a string containing all lowercase letters with zero or more hyphens.
+
+
+
+ Only a limited set of core unit identifiers are allowed. An illegal core unit identifier results in a RangeError.
+
+
+
+
IsWellFormedUnitIdentifier ( _unitIdentifier_ )
+
+
+ The IsWellFormedUnitIdentifier abstract operation verifies that the _unitIdentifier_ argument (which must be a String value) represents a well-formed core unit identifier as defined in UTS #35, Part 2, Section 6. In addition to obeying the UTS #35 core unit identifier syntax, _unitIdentifier_ must be one of the identifiers sanctioned by UTS #35 or be a compound unit composed of two sanctioned simple units. The following steps are taken:
+
+
+
+ 1. If the result of IsSanctionedSimpleUnitIdentifier(_unitIdentifier_) is *true*, then
+ 1. Return *true*.
+ 1. If the substring `"-per-"` does not occur exactly once in _unitIdentifier_, then
+ 1. Return *false*.
+ 1. Let _numerator_ be the substring of _unitIdentifier_ from the beginning to just before `"-per-"`.
+ 1. If the result of IsSanctionedSimpleUnitIdentifier(_numerator_) is *false*, then
+ 1. Return *false*.
+ 1. Let _denominator_ be the substring of _unitIdentifier_ from just after `"-per-"` to the end.
+ 1. If the result of IsSanctionedSimpleUnitIdentifier(_denominator_) is *false*, then
+ 1. Return *false*.
+ 1. Return *true*.
+
+
+
+
+
+ The IsSanctionedSimpleUnitIdentifier abstract operation verifies that the given core unit identifier is among the simple units sanctioned in the current version of the ECMAScript standard, a subset of the Validity Data as described in UTS #35, Part 1, Section 3.11; the list may grow over time. As discussed in UTS #35, a simple unit is one that does not have a numerator and denominator. The following steps are taken:
+
+
+
+ 1. If _unitIdentifier_ is listed in below, return *true*.
+ 1. Else, Return *false*.
+
+
+
+ Simple units sanctioned for use in ECMAScript
+
1Identification of Locales, Currencies, and Time Zones, and Measurement Units
+
+
+ This clause describes the String values used in the ECMAScript 2019 Internationalization API Specification to identify locales, currencies, time zones, and measurement units.
+
+
+
+
+
1.1Case Sensitivity and Case Mapping
+
+
+ The String values used to identify locales, currencies, and time zones are interpreted in a case-insensitive manner, treating the Unicode Basic Latin characters "A" to "Z" (U+0041 to U+005A) as equivalent to the corresponding Basic Latin characters "a" to "z" (U+0061 to U+007A). No other case folding equivalences are applied. When mapping to upper case, a mapping shall be used that maps characters in the range "a" to "z" (U+0061 to U+007A) to the corresponding characters in the range "A" to "Z" (U+0041 to U+005A) and maps no other characters to the latter range.
+
+
+
+
+ EXAMPLES "ß" (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).
+
+
+
+
+
+
1.2Language Tags
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies locales using language tags as defined by IETF BCP 47 (RFCs 5646 and 4647 or their successors), which may include extensions such as those registered through RFC 6067. Their canonical form is specified in RFC 5646 section 4.5 or its successor.
+
+
+
+
+ BCP 47 language tags that meet those validity criteria of RFC 5646 section 2.2.9 that can be verified without reference to the IANA Language Subtag Registry are considered structurally valid. All structurally valid language tags are valid for use with the APIs defined by this standard. However, the set of locales and thus language tags that an implementation supports with adequate localizations is implementation dependent. The constructors Collator, NumberFormat, DateTimeFormat, and PluralRules map the language tags used in requests to locales supported by their respective implementations.
+
+
+
+
+
+
1.2.1Unicode Locale Extension Sequences
+
+
+ This standard uses the term "Unicode locale extension sequence" for any substring of a language tag that is not part of a private use subtag sequence, starts with a separator "-" and the singleton "u", and includes the maximum sequence of following non-singleton subtags and their preceding "-" separators.
+
+
+
+
+
+
1.2.2IsStructurallyValidLanguageTag ( locale )
+
+
+ The IsStructurallyValidLanguageTag abstract operation verifies that the locale argument (which must be a String value)
+
+
+
+
+
represents a well-formed BCP 47 language tag as specified in RFC 5646 section 2.1, or successor,
+
does not include duplicate variant subtags, and
+
does not include duplicate singleton subtags.
+
+
+
+ The abstract operation returns true if locale can be generated from the ABNF grammar in section 2.1 of the RFC, starting with Language-Tag, and does not contain duplicate variant or singleton subtags (other than as a private use subtag). It returns false otherwise. Terminal value characters in the grammar are interpreted as the Unicode equivalents of the ASCII octet values given.
+
+
+
+
+
+
1.2.3CanonicalizeLanguageTag ( locale )
+
+
+ The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized form of the locale argument (which must be a String value that is a structurally valid BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation).
+ A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or successor, to bring the language tag into canonical form, and to regularize the case of the subtags. Furthermore, a conforming implementation shall not take the steps to bring a language tag into "extlang form", nor shall it reorder variant subtags.
+
+
+
+
+ The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include canonicalization rules for the extension subtag sequences they define that go beyond the canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not required, to apply these additional rules.
+
+
+
+
+
+
1.2.4DefaultLocale ()
+
+
+ The DefaultLocale abstract operation returns a String value representing the structurally valid (1.2.2) and canonicalized (1.2.3) BCP 47 language tag for the host environment's current locale.
+
+
+
+
+
+
+
+
1.3Currency Codes
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies currencies using 3-letter currency codes as defined by ISO 4217. Their canonical form is upper case.
+
+
+
+
+ All well-formed 3-letter ISO 4217 currency codes are allowed. However, the set of combinations of currency code and language tag for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, the ISO 4217 currency code is used for formatting.
+
+
+
+
+
1.3.1IsWellFormedCurrencyCode ( currency )
+
+
+ The IsWellFormedCurrencyCode abstract operation verifies that the currency argument (which must be a String value) represents a well-formed 3-letter ISO currency code. The following steps are taken:
+
+
+
+
Let normalized be the result of mapping currency to upper case as described in 1.1.
If the number of elements in normalized is not 3, return false.
If normalized contains any character that is not in the range "A" to "Z" (U+0041 to U+005A), return false.
Return true.
+
+
+
+
+
+
+
1.4Time Zone Names
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies time zones using the Zone and Link names of the IANA Time Zone Database. Their canonical form is the corresponding Zone name in the casing used in the IANA Time Zone Database.
+
+
+
+
+ All registered Zone and Link names are allowed. Implementations must recognize all such names, and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.
+
+
+
+
+
1.4.1IsValidTimeZoneName ( timeZone )
+
+
+ The IsValidTimeZoneName abstract operation verifies that the timeZone argument (which must be a String value) represents a valid Zone or Link name of the IANA Time Zone Database.
+
+
+
+ The abstract operation returns true if timeZone, converted to upper case as described in 1.1, is equal to one of the Zone or Link names of the IANA Time Zone Database, converted to upper case as described in 1.1. It returns false otherwise.
+
+
+
+
+
+
1.4.2CanonicalizeTimeZoneName
+
+
+ The CanonicalizeTimeZoneName abstract operation returns the canonical and case-regularized form of the timeZone argument (which must be a String value that is a valid time zone name as verified by the IsValidTimeZoneName abstract operation). The following steps are taken:
+
+
+
+
Let ianaTimeZone be the Zone or Link name of the IANA Time Zone Database such that timeZone, converted to upper case as described in 1.1, is equal to ianaTimeZone, converted to upper case as described in 1.1.
If ianaTimeZone is a Link name, let ianaTimeZone be the corresponding Zone name as specified in the "backward" file of the IANA Time Zone Database.
If ianaTimeZone is "Etc/UTC" or "Etc/GMT", return "UTC".
Return ianaTimeZone.
+
+
+
+ The Intl.DateTimeFormat constructor allows this time zone name; if the time zone is not specified, the host environment's current time zone is used. Implementations shall support UTC and the host environment's current time zone (if different from UTC) in formatting.
+
+
+
+
+
+
1.4.3DefaultTimeZone ()
+
+
+ The DefaultTimeZone abstract operation returns a String value representing the valid (1.4.1) and canonicalized (1.4.2) time zone name for the host environment's current time zone.
+
+
+
+
+
+
+
+
+
+
1.5Measurement Unit Identifiers
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies measurement units using a core unit identifier as defined by Unicode Technical Standard #35, Part 2, Section 6. Their canonical form is a string containing all lowercase letters with zero or more hyphens.
+
+
+
+
+ Only a limited set of core unit identifiers are allowed. An illegal core unit identifier results in a RangeError.
+
+
+ The IsWellFormedUnitIdentifier abstract operation verifies that the unitIdentifier argument (which must be a String value) represents a well-formed core unit identifier as defined in UTS #35, Part 2, Section 6. In addition to obeying the UTS #35 core unit identifier syntax, unitIdentifier must be one of the identifiers sanctioned by UTS #35 or be a compound unit composed of two sanctioned simple units. The following steps are taken:
+
+
+ The IsSanctionedSimpleUnitIdentifier abstract operation verifies that the given core unit identifier is among the simple units sanctioned in the current version of the ECMAScript standard, a subset of the Validity Data as described in UTS #35, Part 1, Section 3.11; the list may grow over time. As discussed in UTS #35, a simple unit is one that does not have a numerator and denominator. The following steps are taken:
+
+
+
+
If unitIdentifier is listed in Table 1 below, return true.
Else, Return false.
+
+
+
Table 1: Simple units sanctioned for use in ECMAScript
+
+
+
+
+
Simple Unit
+
+
+
acre
+
bit
+
byte
+
celsius
+
centimeter
+
day
+
degree
+
fahrenheit
+
fluid-ounce
+
foot
+
gallon
+
gigabit
+
gigabyte
+
gram
+
hectare
+
hour
+
inch
+
kilobit
+
kilobyte
+
kilogram
+
kilometer
+
liter
+
megabit
+
megabyte
+
meter
+
mile
+
mile-scandinavian
+
millimeter
+
milliliter
+
millisecond
+
minute
+
month
+
ounce
+
percent
+
petabyte
+
pound
+
second
+
stone
+
terabit
+
terabyte
+
week
+
yard
+
year
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/section6/locales-currencies-tz_proposed.html b/section6/locales-currencies-tz_proposed.html
new file mode 100644
index 0000000..b21b8e8
--- /dev/null
+++ b/section6/locales-currencies-tz_proposed.html
@@ -0,0 +1,261 @@
+
+
Identification of Locales, Currencies, Time Zones, and Measurement Units
+
+
+ This clause describes the String values used in the ECMAScript 2019 Internationalization API Specification to identify locales, currencies, time zones, and measurement units.
+
+
+
+
Case Sensitivity and Case Mapping
+
+
+ The String values used to identify locales, currencies, and time zones are interpreted in a case-insensitive manner, treating the Unicode Basic Latin characters `"A"` to `"Z"` (U+0041 to U+005A) as equivalent to the corresponding Basic Latin characters `"a"` to `"z"` (U+0061 to U+007A). No other case folding equivalences are applied. When mapping to upper case, a mapping shall be used that maps characters in the range `"a"` to `"z"` (U+0061 to U+007A) to the corresponding characters in the range `"A"` to `"Z"` (U+0041 to U+005A) and maps no other characters to the latter range.
+
+
+
+ EXAMPLES `"ß"` (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).
+
+
+
+
+
Language Tags
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies locales using language tags as defined by IETF BCP 47 (RFCs 5646 and 4647 or their successors), which may include extensions such as those registered through RFC 6067. Their canonical form is specified in RFC 5646 section 4.5 or its successor.
+
+
+
+ BCP 47 language tags that meet those validity criteria of RFC 5646 section 2.2.9 that can be verified without reference to the IANA Language Subtag Registry are considered structurally valid. All structurally valid language tags are valid for use with the APIs defined by this standard. However, the set of locales and thus language tags that an implementation supports with adequate localizations is implementation dependent. The constructors Collator, NumberFormat, DateTimeFormat, and PluralRules map the language tags used in requests to locales supported by their respective implementations.
+
+
+
+
+
Unicode Locale Extension Sequences
+
+
+ This standard uses the term `"Unicode locale extension sequence"` for any substring of a language tag that is not part of a private use subtag sequence, starts with a separator `"-"` and the singleton `"u"`, and includes the maximum sequence of following non-singleton subtags and their preceding `"-"` separators.
+
+
+
+
+
IsStructurallyValidLanguageTag ( _locale_ )
+
+
+ The IsStructurallyValidLanguageTag abstract operation verifies that the _locale_ argument (which must be a String value)
+
+
+
+
represents a well-formed BCP 47 language tag as specified in RFC 5646 section 2.1, or successor,
+
does not include duplicate variant subtags, and
+
does not include duplicate singleton subtags.
+
+
+
+ The abstract operation returns true if _locale_ can be generated from the ABNF grammar in section 2.1 of the RFC, starting with Language-Tag, and does not contain duplicate variant or singleton subtags (other than as a private use subtag). It returns false otherwise. Terminal value characters in the grammar are interpreted as the Unicode equivalents of the ASCII octet values given.
+
+
+
+
+
CanonicalizeLanguageTag ( _locale_ )
+
+
+ The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized form of the _locale_ argument (which must be a String value that is a structurally valid BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation).
+ A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or successor, to bring the language tag into canonical form, and to regularize the case of the subtags. Furthermore, a conforming implementation shall not take the steps to bring a language tag into `"extlang form"`, nor shall it reorder variant subtags.
+
+
+
+ The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include canonicalization rules for the extension subtag sequences they define that go beyond the canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not required, to apply these additional rules.
+
+
+
+
+
DefaultLocale ()
+
+
+ The DefaultLocale abstract operation returns a String value representing the structurally valid () and canonicalized () BCP 47 language tag for the host environment's current locale.
+
+
+
+
+
+
+
Currency Codes
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies currencies using 3-letter currency codes as defined by ISO 4217. Their canonical form is upper case.
+
+
+
+ All well-formed 3-letter ISO 4217 currency codes are allowed. However, the set of combinations of currency code and language tag for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, the ISO 4217 currency code is used for formatting.
+
+
+
+
IsWellFormedCurrencyCode ( _currency_ )
+
+
+ The IsWellFormedCurrencyCode abstract operation verifies that the _currency_ argument (which must be a String value) represents a well-formed 3-letter ISO currency code. The following steps are taken:
+
+
+
+ 1. Let _normalized_ be the result of mapping _currency_ to upper case as described in .
+ 1. If the number of elements in _normalized_ is not 3, return *false*.
+ 1. If _normalized_ contains any character that is not in the range `"A"` to `"Z"` (U+0041 to U+005A), return *false*.
+ 1. Return *true*.
+
+
+
+
+
+
+
Time Zone Names
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies time zones using the Zone and Link names of the IANA Time Zone Database. Their canonical form is the corresponding Zone name in the casing used in the IANA Time Zone Database.
+
+
+
+ All registered Zone and Link names are allowed. Implementations must recognize all such names, and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.
+
+
+
+
IsValidTimeZoneName ( _timeZone_ )
+
+
+ The IsValidTimeZoneName abstract operation verifies that the _timeZone_ argument (which must be a String value) represents a valid Zone or Link name of the IANA Time Zone Database.
+
+
+ The abstract operation returns true if _timeZone_, converted to upper case as described in , is equal to one of the Zone or Link names of the IANA Time Zone Database, converted to upper case as described in . It returns false otherwise.
+
+
+
+
+
CanonicalizeTimeZoneName
+
+
+ The CanonicalizeTimeZoneName abstract operation returns the canonical and case-regularized form of the _timeZone_ argument (which must be a String value that is a valid time zone name as verified by the IsValidTimeZoneName abstract operation). The following steps are taken:
+
+
+
+ 1. Let _ianaTimeZone_ be the Zone or Link name of the IANA Time Zone Database such that _timeZone_, converted to upper case as described in , is equal to _ianaTimeZone_, converted to upper case as described in .
+ 1. If _ianaTimeZone_ is a Link name, let _ianaTimeZone_ be the corresponding Zone name as specified in the `"backward"` file of the IANA Time Zone Database.
+ 1. If _ianaTimeZone_ is `"Etc/UTC"` or `"Etc/GMT"`, return `"UTC"`.
+ 1. Return _ianaTimeZone_.
+
+
+
+ The Intl.DateTimeFormat constructor allows this time zone name; if the time zone is not specified, the host environment's current time zone is used. Implementations shall support UTC and the host environment's current time zone (if different from UTC) in formatting.
+
+
+
+
+
DefaultTimeZone ()
+
+
+ The DefaultTimeZone abstract operation returns a String value representing the valid () and canonicalized () time zone name for the host environment's current time zone.
+
+
+
+
+
+
+
Measurement Unit Identifiers
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies measurement units using a core unit identifier as defined by Unicode Technical Standard #35, Part 2, Section 6. Their canonical form is a string containing all lowercase letters with zero or more hyphens.
+
+
+
+ Only a limited set of core unit identifiers are allowed. An illegal core unit identifier results in a RangeError.
+
+
+
+
IsWellFormedUnitIdentifier ( _unitIdentifier_ )
+
+
+ The IsWellFormedUnitIdentifier abstract operation verifies that the _unitIdentifier_ argument (which must be a String value) represents a well-formed core unit identifier as defined in UTS #35, Part 2, Section 6. In addition to obeying the UTS #35 core unit identifier syntax, _unitIdentifier_ must be one of the identifiers sanctioned by UTS #35 or be a compound unit composed of two sanctioned simple units. The following steps are taken:
+
+
+
+ 1. If the result of IsSanctionedSimpleUnitIdentifier(_unitIdentifier_) is *true*, then
+ 1. Return *true*.
+ 1. If the substring `"-per-"` does not occur exactly once in _unitIdentifier_, then
+ 1. Return *false*.
+ 1. Let _numerator_ be the substring of _unitIdentifier_ from the beginning to just before `"-per-"`.
+ 1. If the result of IsSanctionedSimpleUnitIdentifier(_numerator_) is *false*, then
+ 1. Return *false*.
+ 1. Let _denominator_ be the substring of _unitIdentifier_ from just after `"-per-"` to the end.
+ 1. If the result of IsSanctionedSimpleUnitIdentifier(_denominator_) is *false*, then
+ 1. Return *false*.
+ 1. Return *true*.
+
+
+
+
+
+ The IsSanctionedSimpleUnitIdentifier abstract operation verifies that the given core unit identifier is among the simple units sanctioned in the current version of the ECMAScript standard, a subset of the Validity Data as described in UTS #35, Part 1, Section 3.11; the list may grow over time. As discussed in UTS #35, a simple unit is one that does not have a numerator and denominator. The following steps are taken:
+
+
+
+ 1. If _unitIdentifier_ is listed in below, return *true*.
+ 1. Else, Return *false*.
+
+
+
+ Simple units sanctioned for use in ECMAScript
+
1Identification of Locales, Currencies, Time Zones, and Measurement Units
+
+
+ This clause describes the String values used in the ECMAScript 2019 Internationalization API Specification to identify locales, currencies, time zones, and measurement units.
+
+
+
+
+
1.1Case Sensitivity and Case Mapping
+
+
+ The String values used to identify locales, currencies, and time zones are interpreted in a case-insensitive manner, treating the Unicode Basic Latin characters "A" to "Z" (U+0041 to U+005A) as equivalent to the corresponding Basic Latin characters "a" to "z" (U+0061 to U+007A). No other case folding equivalences are applied. When mapping to upper case, a mapping shall be used that maps characters in the range "a" to "z" (U+0061 to U+007A) to the corresponding characters in the range "A" to "Z" (U+0041 to U+005A) and maps no other characters to the latter range.
+
+
+
+
+ EXAMPLES "ß" (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).
+
+
+
+
+
+
1.2Language Tags
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies locales using language tags as defined by IETF BCP 47 (RFCs 5646 and 4647 or their successors), which may include extensions such as those registered through RFC 6067. Their canonical form is specified in RFC 5646 section 4.5 or its successor.
+
+
+
+
+ BCP 47 language tags that meet those validity criteria of RFC 5646 section 2.2.9 that can be verified without reference to the IANA Language Subtag Registry are considered structurally valid. All structurally valid language tags are valid for use with the APIs defined by this standard. However, the set of locales and thus language tags that an implementation supports with adequate localizations is implementation dependent. The constructors Collator, NumberFormat, DateTimeFormat, and PluralRules map the language tags used in requests to locales supported by their respective implementations.
+
+
+
+
+
+
1.2.1Unicode Locale Extension Sequences
+
+
+ This standard uses the term "Unicode locale extension sequence" for any substring of a language tag that is not part of a private use subtag sequence, starts with a separator "-" and the singleton "u", and includes the maximum sequence of following non-singleton subtags and their preceding "-" separators.
+
+
+
+
+
+
1.2.2IsStructurallyValidLanguageTag ( locale )
+
+
+ The IsStructurallyValidLanguageTag abstract operation verifies that the locale argument (which must be a String value)
+
+
+
+
+
represents a well-formed BCP 47 language tag as specified in RFC 5646 section 2.1, or successor,
+
does not include duplicate variant subtags, and
+
does not include duplicate singleton subtags.
+
+
+
+ The abstract operation returns true if locale can be generated from the ABNF grammar in section 2.1 of the RFC, starting with Language-Tag, and does not contain duplicate variant or singleton subtags (other than as a private use subtag). It returns false otherwise. Terminal value characters in the grammar are interpreted as the Unicode equivalents of the ASCII octet values given.
+
+
+
+
+
+
1.2.3CanonicalizeLanguageTag ( locale )
+
+
+ The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized form of the locale argument (which must be a String value that is a structurally valid BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation).
+ A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or successor, to bring the language tag into canonical form, and to regularize the case of the subtags. Furthermore, a conforming implementation shall not take the steps to bring a language tag into "extlang form", nor shall it reorder variant subtags.
+
+
+
+
+ The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include canonicalization rules for the extension subtag sequences they define that go beyond the canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not required, to apply these additional rules.
+
+
+
+
+
+
1.2.4DefaultLocale ()
+
+
+ The DefaultLocale abstract operation returns a String value representing the structurally valid (1.2.2) and canonicalized (1.2.3) BCP 47 language tag for the host environment's current locale.
+
+
+
+
+
+
+
+
1.3Currency Codes
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies currencies using 3-letter currency codes as defined by ISO 4217. Their canonical form is upper case.
+
+
+
+
+ All well-formed 3-letter ISO 4217 currency codes are allowed. However, the set of combinations of currency code and language tag for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, the ISO 4217 currency code is used for formatting.
+
+
+
+
+
1.3.1IsWellFormedCurrencyCode ( currency )
+
+
+ The IsWellFormedCurrencyCode abstract operation verifies that the currency argument (which must be a String value) represents a well-formed 3-letter ISO currency code. The following steps are taken:
+
+
+
+
Let normalized be the result of mapping currency to upper case as described in 1.1.
If the number of elements in normalized is not 3, return false.
If normalized contains any character that is not in the range "A" to "Z" (U+0041 to U+005A), return false.
Return true.
+
+
+
+
+
+
+
1.4Time Zone Names
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies time zones using the Zone and Link names of the IANA Time Zone Database. Their canonical form is the corresponding Zone name in the casing used in the IANA Time Zone Database.
+
+
+
+
+ All registered Zone and Link names are allowed. Implementations must recognize all such names, and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.
+
+
+
+
+
1.4.1IsValidTimeZoneName ( timeZone )
+
+
+ The IsValidTimeZoneName abstract operation verifies that the timeZone argument (which must be a String value) represents a valid Zone or Link name of the IANA Time Zone Database.
+
+
+
+ The abstract operation returns true if timeZone, converted to upper case as described in 1.1, is equal to one of the Zone or Link names of the IANA Time Zone Database, converted to upper case as described in 1.1. It returns false otherwise.
+
+
+
+
+
+
1.4.2CanonicalizeTimeZoneName
+
+
+ The CanonicalizeTimeZoneName abstract operation returns the canonical and case-regularized form of the timeZone argument (which must be a String value that is a valid time zone name as verified by the IsValidTimeZoneName abstract operation). The following steps are taken:
+
+
+
+
Let ianaTimeZone be the Zone or Link name of the IANA Time Zone Database such that timeZone, converted to upper case as described in 1.1, is equal to ianaTimeZone, converted to upper case as described in 1.1.
If ianaTimeZone is a Link name, let ianaTimeZone be the corresponding Zone name as specified in the "backward" file of the IANA Time Zone Database.
If ianaTimeZone is "Etc/UTC" or "Etc/GMT", return "UTC".
Return ianaTimeZone.
+
+
+
+ The Intl.DateTimeFormat constructor allows this time zone name; if the time zone is not specified, the host environment's current time zone is used. Implementations shall support UTC and the host environment's current time zone (if different from UTC) in formatting.
+
+
+
+
+
+
1.4.3DefaultTimeZone ()
+
+
+ The DefaultTimeZone abstract operation returns a String value representing the valid (1.4.1) and canonicalized (1.4.2) time zone name for the host environment's current time zone.
+
+
+
+
+
+
+
+
1.5Measurement Unit Identifiers
+
+
+ The ECMAScript 2019 Internationalization API Specification identifies measurement units using a core unit identifier as defined by Unicode Technical Standard #35, Part 2, Section 6. Their canonical form is a string containing all lowercase letters with zero or more hyphens.
+
+
+
+
+ Only a limited set of core unit identifiers are allowed. An illegal core unit identifier results in a RangeError.
+
+
+ The IsWellFormedUnitIdentifier abstract operation verifies that the unitIdentifier argument (which must be a String value) represents a well-formed core unit identifier as defined in UTS #35, Part 2, Section 6. In addition to obeying the UTS #35 core unit identifier syntax, unitIdentifier must be one of the identifiers sanctioned by UTS #35 or be a compound unit composed of two sanctioned simple units. The following steps are taken:
+
+
+ The IsSanctionedSimpleUnitIdentifier abstract operation verifies that the given core unit identifier is among the simple units sanctioned in the current version of the ECMAScript standard, a subset of the Validity Data as described in UTS #35, Part 1, Section 3.11; the list may grow over time. As discussed in UTS #35, a simple unit is one that does not have a numerator and denominator. The following steps are taken:
+
+
+
+
If unitIdentifier is listed in Table 1 below, return true.
Else, Return false.
+
+
+
Table 1: Simple units sanctioned for use in ECMAScript
+
+
+
+
+
Simple Unit
+
+
+
acre
+
bit
+
byte
+
celsius
+
centimeter
+
day
+
degree
+
fahrenheit
+
fluid-ounce
+
foot
+
gallon
+
gigabit
+
gigabyte
+
gram
+
hectare
+
hour
+
inch
+
kilobit
+
kilobyte
+
kilogram
+
kilometer
+
liter
+
megabit
+
megabyte
+
meter
+
mile
+
mile-scandinavian
+
millimeter
+
milliliter
+
millisecond
+
minute
+
month
+
ounce
+
percent
+
petabyte
+
pound
+
second
+
stone
+
terabit
+
terabyte
+
week
+
yard
+
year
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spec.emu b/spec.emu
deleted file mode 100644
index 5cf3229..0000000
--- a/spec.emu
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-title: Proposal Title Goes Here
-stage: -1
-contributors: Your Name Goes Here
-
-
-
-
This is an emu-clause
-
This is an algorithm:
-
- 1. Let _proposal_ be *undefined*.
- 1. If IsAccepted(_proposal_),
- 1. Let _stage_ be *0*.
- 1. Else,
- 1. Let _stage_ be *-1*.
- 1. Return ? ToString(_proposal_).
-
-