1 of 18

Intl.NumberFormat Feature Proposal for Stage 3

Shane Carr, Google, sffc@google.com

November 2018

https://github.com/tc39-transfer/proposal-unified-intl-numberformat

2 of 18

Background: Intl.NumberFormat Examples (from MDN)

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }) .format(number)); // expected output: "123.456,79 €"��// the Japanese yen doesn't use a minor unitconsole.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }) .format(number)); // expected output: "¥123,457"��// limit to three significant digits and use Number.prototype.toLocaleStringconsole.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));�// expected output: "1,23,000"

3 of 18

Background/Motivation

Many requests from users to add more number formatting features to ECMA-402

These features are important to both end users and to Google

  • Locale data footprint
  • Barrier to entry

This proposal adds features to Intl.NumberFormat, as opposed to creating new constructors and increased overlapping functionality.

https://github.com/sffc/proposal-unified-intl-numberformat

4 of 18

Proposal: Four Sections

  • Spec Cleanup
  • Units
  • Scientific and Compact Notation
  • Sign Display

https://github.com/sffc/proposal-unified-intl-numberformat

5 of 18

I. Spec Cleanup

https://github.com/sffc/proposal-unified-intl-numberformat

6 of 18

Spec Updates (Limited Behavior Changes)

A few sections of the spec have been refactored:

  • Fix locale data for currency plural forms (tc39/ecma402#238)
  • Move pattern resolution out of the constructor to keep all internal fields of NumberFormat locale-agnostic

In addition, a missing option is added to the existing currencyDisplay setting: "narrow-symbol".

(100).toLocaleString("en-CA", {� style: "currency",� currency: "USD",� currencyDisplay: "narrow-symbol"�});�// ==> "$100" (rather than "US$100")

https://github.com/sffc/proposal-unified-intl-numberformat

7 of 18

II. Units

https://github.com/sffc/proposal-unified-intl-numberformat

8 of 18

Units

Add new style entry: "unit".

Add new key unit, which accepts a core unit identifier, defined in Unicode Technical Standard 35.

  • length-meter
  • mile-per-hour
  • kelvin
  • … 140+ available, listed in spec

New key unitDisplay, taking either "narrow", "short", or "long", to define what form of unit affix to render.

(16).toLocaleString("en-GB", {� style: "unit",� unit: "liter",� unitDisplay: "long"�});�// ==> "16 litres"

(75).toLocaleString("jp-JP", {� style: "unit",� unit: "fahrenheit",� unitDisplay: "narrow"�});�// ==> "75°"

https://github.com/sffc/proposal-unified-intl-numberformat

9 of 18

III. Scientific and Compact Notation

https://github.com/sffc/proposal-unified-intl-numberformat

10 of 18

Scientific and Compact Notation

Scientific and compact notation are represented by the new option notation

notation takes either "scientific", "engineering", "compact", or "plain"

compactDisplay, used only when notation is "compact", takes either "short" or "long"

(987654321).toLocaleString("en-US", {� notation: "scientific"�});�// ==> 9.877E8��(987654321).toLocaleString("en-US", {� notation: "engineering"�});�// ==> 987.7E6��(987654321).toLocaleString("zh-CN", {� notation: "compact"�});�// ==> 9.9亿

https://github.com/sffc/proposal-unified-intl-numberformat

11 of 18

IV. Sign Display Options

https://github.com/sffc/proposal-unified-intl-numberformat

12 of 18

Sign Display

signDisplay: "auto" (default), "always", "never", "except-zero"; choices based on user needs with a focus on Google

signDisplay

-1

0

1

auto

-1

0

1

always

-1

+0

+1

never

1

0

1

except-zero

-1

0

+1

(55).toLocaleString("my-MM", {� signDisplay: "always"�});�// ==> +၅၅

https://github.com/sffc/proposal-unified-intl-numberformat

13 of 18

Currency Sign

currencySign: "standard" (default), "accounting".

Accounting often displays negative numbers with parentheses.

(-100).toLocaleString("bn", {� style: "currency",� currency: "EUR",� currencySign: "accounting"�});�// ==> (১০০.০০€)

https://github.com/sffc/proposal-unified-intl-numberformat

14 of 18

Combining Options

Most proposed options are orthogonal, which means they can be combined in arbitrary ways. ICU will print correctly localized strings.

(2000).toLocaleString("en-US", {� style: "unit",� unit: "foodcalorie",� unitDisplay: "long",� notation: "compact",� compactDisplay: "long",� sign: "except-zero"�});�// ==> +2 thousand Calories

https://github.com/sffc/proposal-unified-intl-numberformat

15 of 18

Changes from July

https://github.com/sffc/proposal-unified-intl-numberformat

16 of 18

Changes from July

  • Core unit identifier: units no longer need the type prefix. Also allows for custom compound units supported by CLDR.
  • Compact notation uses its own rounding strategy unless the user provides their own.
  • Changed “camelCase” to “kebab-case” in string options.
  • Distinguish -0.0 from 0.0.
  • minimumIntegerDigits works for significant digit rounding.
  • Format-to-parts field names changed according to Ecma 402 subcommittee recommendation.
  • Explicit list of unit identifiers added to spec.
  • Spec language cleanup based on review feedback.

https://github.com/sffc/proposal-unified-intl-numberformat

17 of 18

Thank You! (Stage 3 reviewers)

zenparsing, gsathya

Additional thanks to:

rxaviers, Ms2ger, littledan

ECMA 402 Subcommittee

Google i18n Team

https://github.com/sffc/proposal-unified-intl-numberformat

18 of 18

For Advancement to Stage 3?

  • Spec text is reviewed
  • All feedback is addressed

https://github.com/sffc/proposal-unified-intl-numberformat