You might already be familiar with the Intl.NumberFormat API, as it’s been supported across modern environments for a while now.

  • Chrome: supported since version 24
  • Firefox: supported since version 29
  • Safari: supported since version 10
  • Node.js: supported since version 0.12
  • Babel: supported

about this feature support listing

In its most basic form, Intl.NumberFormat lets you create a reusable formatter instance that supports locale-aware number formatting. Just like other Intl.*Format APIs, a formatter instance supports both a format and a formatToParts method:

const formatter = new Intl.NumberFormat('en');
formatter.format(987654.321);
// → '987,654.321'
formatter.formatToParts(987654.321);
// → [
// → { type: 'integer', value: '987' },
// → { type: 'group', value: ',' },
// → { type: 'integer', value: '654' },
// → { type: 'decimal', value: '.' },
// → { type: 'fraction', value: '321' }
// → ]

Note: Although much of the Intl.NumberFormat functionality can be achieved using Number.prototype.toLocaleString, Intl.NumberFormat is often the better choice, since it enables creating a re-usable formatter instance which tends to be more efficient.

Recently, the Intl.NumberFormat API gained some new capabilities.

BigInt support

In addition to Numbers, Intl.NumberFormat can now also format BigInts:

const formatter = new Intl.NumberFormat('fr');
formatter.format(12345678901234567890n);
// → '12 345 678 901 234 567 890'
formatter.formatToParts(123456n);
// → [
// → { type: 'integer', value: '123' },
// → { type: 'group', value: ' ' },
// → { type: 'integer', value: '456' }
// → ]

about this feature support listing

Units of measurement

Intl.NumberFormat currently supports the following so-called simple units:

  • angle: degree
  • area: acre, hectare
  • concentration: percent
  • digital: bit, byte, kilobit, kilobyte, megabit, megabyte, gigabit, gigabyte, terabit, terabyte, petabyte
  • duration: millisecond, second, minute, hour, day, week, month, year
  • length: millimeter, centimeter, meter, kilometer, inch, foot, yard, mile, mile-scandinavian
  • mass: gram, kilogram, ounce, pound, stone
  • temperature: celsius, fahrenheit
  • volume: liter, milliliter, gallon, fluid-ounce

To format numbers with localized units, use the style and unit options:

const formatter = new Intl.NumberFormat('en', {
 style: 'unit',
 unit: 'kilobyte',
});
formatter.format(1.234);
// → '1.234 kB'
formatter.format(123.4);
// → '123.4 kB'

Note that over time, support for more units may be added. Please refer to the spec for the latest up-to-date list.

The above simple units can be combined into arbitrary numerator and denominator pairs to express compound units such as “liters per acre” or “meters per second”:

const formatter = new Intl.NumberFormat('en', {
 style: 'unit',
 unit: 'meter-per-second',
});
formatter.format(299792458);
// → '299,792,458 m/s'
  • Chrome: supported since version 77
  • Firefox: no support
  • Safari: no support
  • Node.js: no support
  • Babel: no support

about this feature support listing

Compact, scientific, and engineering notation

Compact notation uses locale-specific symbols to represent large numbers. It is a more human-friendly alternative to scientific notation:

{
 // Test standard notation.
 const formatter = new Intl.NumberFormat('en', {
 notation: 'standard', // This is the implied default.
 });
 formatter.format(1234.56);
 // → '1,234.56'
 formatter.format(123456);
 // → '123,456'
 formatter.format(123456789);
 // → '123,456,789'
}

{
// Test compact notation.
const formatter = new Intl.NumberFormat(‘en’, {
notation: ‘compact’,
});
formatter.format(1234.56);
// → ‘1.2K’
formatter.format(123456);
// → ‘123K’
formatter.format(123456789);
// → ‘123M’
}

Note: By default, compact notation rounds to the nearest integer, but always keeps 2 significant digits. You can set any of {minimum,maximum}FractionDigits or {minimum,maximum}SignificantDigits to override that behavior.

Intl.NumberFormat can also format numbers in scientific notation:

const formatter = new Intl.NumberFormat(‘en’, {
style: ‘unit’,
unit: ‘meter-per-second’,
notation: ‘scientific’,
});
formatter.format(299792458);
// → ‘2.998E8 m/s’

Engineering notation is supported as well:

const formatter = new Intl.NumberFormat(‘en’, {
style: ‘unit’,
unit: ‘meter-per-second’,
notation: ‘engineering’,
});
formatter.format(299792458);
// → ‘299.792E6 m/s’
  • Chrome: supported since version 77
  • Firefox: no support
  • Safari: no support
  • Node.js: no support
  • Babel: no support

about this feature support listing

Sign display

In certain situations (such as presenting deltas) it helps to explicitly display the sign, even when the number is positive. The new signDisplay option enables this:

const formatter = new Intl.NumberFormat(‘en’, {
style: ‘unit’,
unit: ‘percent’,
signDisplay: ‘always’,
});
formatter.format(-12.34);
// → ‘-12.34%’
formatter.format(12.34);
// → ‘+12.34%’
formatter.format(0);
// → ‘+0%’
formatter.format(-0);
// → ‘-0%’

To prevent showing the sign when the value is 0, use signDisplay: ‘exceptZero’:

const formatter = new Intl.NumberFormat(‘en’, {
style: ‘unit’,
unit: ‘percent’,
signDisplay: ‘exceptZero’,
});
formatter.format(-12.34);
// → ‘-12.34%’
formatter.format(12.34);
// → ‘+12.34%’
formatter.format(0);
// → ‘0%’
// Note: -0 still displays with a sign, as you’d expect:
formatter.format(-0);
// → ‘-0%’

For currency, the currencySign option enables the accounting format, which enables a locale-specific format for negative currency amounts; for example, wrapping the amount in parentheses:

const formatter = new Intl.NumberFormat(‘en’, {
style: ‘currency’,
currency: ‘USD’,
signDisplay: ‘exceptZero’,
currencySign: ‘accounting’,
});
formatter.format(-12.34);
// → ‘($12.34)’
formatter.format(12.34);
// → ‘+$12.34’
formatter.format(0);
// → ‘$0.00’
formatter.format(-0);
// → ‘($0.00)’
  • Chrome: supported since version 77
  • Firefox: no support
  • Safari: no support
  • Node.js: no support
  • Babel: no support

about this feature support listing

More info

The relevant spec proposal has more information and examples, including guidance on how to feature-detect each individual Intl.NumberFormat feature.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

React vs Angular vs Vue.js by Example

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Creating Web Animations with Anime.js


#javascript #web-development

`Intl.NumberFormat` and Its New Capabilities
25.30 GEEK