International Number Formatting with the Intl Library: A Comprehensive Guide

JavaScript
5 minutes read

Introduction

When developing software for a global audience, localization becomes a crucial aspect of your application, and one such element is number formatting. The way numbers, currencies, and percentages are formatted can vary greatly from region to region, and getting it wrong can confuse or even alienate users. A well-internationalized application caters to these nuances, delivering a seamless user experience across the globe.

Basics of Number Formatting with Intl

The Intl library, a key player in the JavaScript ecosystem, comes in handy for internationalizing applications. Among its many features, it provides the NumberFormat class for locale-specific number formatting.

With NumberFormat, we can format numbers according to different styles: decimal, currency, or percentage, all following locale-specific conventions. It also supports formatting plain numbers, making it a versatile tool for internationalization.

For example, formatting the number 1234567.89 as 1,234,567.89 in the English (United States) locale, or 1.234.567,89 in the Dutch (Netherlands) locale. 

Formatting Plain Numbers

When it comes to formatting plain numbers, NumberFormat provides options to customize the decimal precision, use grouping separators like commas for larger numbers, and choose different rounding modes.

Let’s explore some use cases for plain numbers formatting:

Basic Number Formatting

let formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(1234567.89)); // Outputs: "1,234,567.89"

This code formats the number 1234567.89 into a string with group separators (commas) following the conventions of the en-US locale.

Number Formatting with Decimal Precision

let formatter = new Intl.NumberFormat('en-US', { 
  minimumFractionDigits: 2, 
  maximumFractionDigits: 2 
});

console.log(formatter.format(1234567)); // Outputs: "1,234,567.00"

This formats a whole number 1234567 into a string, ensuring two digits after the decimal point as specified by minimumFractionDigits and maximumFractionDigits.

Number Formatting Without Group Separators

let formatter = new Intl.NumberFormat('en-US', { 
  useGrouping: false 
});

console.log(formatter.format(1234567.89)); // Outputs: "1234567.89"

useGrouping: false is used to format the number without any group (comma) separators.

 Negative Number Formatting

let formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(-1234567.89)); // Outputs: "-1,234,567.89"

Here, the negative number -1234567.89 is formatted according to the en-US locale.

Scientific Notation

let formatter = new Intl.NumberFormat('en-US', { 
  notation: 'scientific'
});

console.log(formatter.format(1234567)); // Outputs: "1.23E6"

By using notation: 'scientific', the number is formatted into a string representation of scientific notation

Engineering Notation

let formatter = new Intl.NumberFormat('en-US', { 
  notation: 'engineering'
});

console.log(formatter.format(1234567)); // Outputs: "1.234567E6"

notation: 'engineering' is used to format the number into a string representation in engineering notation.

Compact Notation

let formatter = new Intl.NumberFormat('en-US', { 
  notation: 'compact',
  compactDisplay: 'long'
});

console.log(formatter.format(1234567)); // Outputs: "1.2 million"

Here, the notation: 'compact' and compactDisplay: 'long' options are used to format the number into a compact string representation in the en-US locale.

Rounding Mode

let formatter = new Intl.NumberFormat('en-US', { 
  maximumFractionDigits: 1,
  roundingMode: 'floor'
});

console.log(formatter.format(1234567.89)); // Outputs: "1,234,567.8"

In this snippet, maximumFractionDigits: 1 specifies one digit after the decimal point, and roundingMode: 'floor' rounds down to the nearest value.

Formatting in Different Locale

let formatter = new Intl.NumberFormat('de-DE');
console.log(formatter.format(1234567.89)); // Outputs: "1.234.567,89"

This code snippet formats the number according to the de-DE (German) locale, which uses a period as a group separator and a comma as a decimal separator.

Changing Decimal and Grouping Separator

let formatter = new Intl.NumberFormat('fr-FR');
console.log(formatter.format(1234567.89)); // Outputs: "1 234 567,89"

Here, the number is formatted according to the fr-FR (French) locale, which uses a space as a group separator and a comma as a decimal separator.

Formatting Currencies

For global applications, properly formatting currencies is essential. The NumberFormat class allows you to specify the currency code or symbol, and customize decimal precision and symbol placement.

Let’s explore some use cases for currency formatting:

Currency Formatting

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD' 
});

console.log(formatter.format(1234567.89)); // Outputs: "$1,234,567.89"

This formats the number into a currency string using the USD currency code. The style: 'currency' option specifies that the output string should represent a currency value.

Currency Formatting with Different Locale

let formatter = new Intl.NumberFormat('de-DE', { 
  style: 'currency', 
  currency: 'EUR' 
});

console.log(formatter.format(1234567.89)); // Outputs: "1.234.567,89 €"

Here, the number is formatted into a currency string using the EUR currency code and de-DE locale. The currency symbol is placed after the number as per German conventions.

Changing Currency Display Style

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD',
  currencyDisplay: 'name'
});

console.log(formatter.format(1234567.89)); // Outputs: "1,234,567.89 US dollars"

currencyDisplay: 'name' changes the display of the currency from its symbol ($) to its full name (US dollars).

Compact Currency Notation

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD', 
  notation: 'compact' 
});

console.log(formatter.format(1234567.89)); // Outputs: "$1.2M"

By using notation: 'compact', the formatted string represents the number in a compact format, using M to represent millions.

Minimum/Maximum Fraction Digits

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD',
  minimumFractionDigits: 0,
  maximumFractionDigits: 0 
});

console.log(formatter.format(1234567.89)); // Outputs: "$1,234,568"

By setting minimumFractionDigits: 0 and maximumFractionDigits: 0, the formatted string rounds to the nearest whole number, with no decimal part.

Using Different Rounding Modes

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD',
  roundingMode: 'ceiling'
});

console.log(formatter.format(1234567.89)); // Outputs: "$1,234,567.90"

roundingMode: 'ceiling' ensures that the formatted string rounds up to the nearest cent.

Currency Formatting with Small Decimal Values

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'JPY' 
});
console.log(formatter.format(1234567)); // Outputs: "¥1,234,567"

The JPY currency does not have a decimal part, so no decimal or fraction part is displayed in the formatted string.

Large Currency Amounts


let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD', 
  notation: 'scientific' 
});

console.log(formatter.format(1234567.89)); // Outputs: "$1.23E6"

notation: 'scientific' is used to represent large currency amounts in a compact, scientific notation form.

Currency with Negative Value

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD' 
});

console.log(formatter.format(-1234567.89)); // Outputs: "-$1,234,567.89"

Negative values are prefixed with a minus sign - in the formatted string.

Using Minimum Integer Digits

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD', 
  minimumIntegerDigits: 5 
});

console.log(formatter.format(123)); // Outputs: "$00,123.00"

minimumIntegerDigits: 5 ensures that the integer part of the formatted string has at least five digits, padding with zeroes if necessary.

Formatting Percentages

Percentage formatting is another common use case, especially in financial or data-driven applications. NumberFormat lets you control decimal precision and the placement of the percentage symbol.

Let’s explore some use cases for percentages formatting:

Basic Percentage Formatting

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'percent' 
});

console.log(formatter.format(0.123)); // Outputs: "12%"

This code formats the number 0.123 into a percentage string according to the en-US locale.

Percentage Formatting with Decimal Precision

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'percent',
  minimumFractionDigits: 2, 
  maximumFractionDigits: 2 
});

console.log(formatter.format(0.123)); // Outputs: "12.30%"

This formats a decimal number 0.123 into a percentage string, ensuring two digits after the decimal point.

Changing the Number of Significant Digits

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'percent',
  minimumSignificantDigits: 3, 
  maximumSignificantDigits: 3 
});

console.log(formatter.format(0.1234)); // Outputs: "12.3%"

minimumSignificantDigits and maximumSignificantDigits are used to format the percentage with three significant digits.

Large Percentage Amounts

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'percent',
  notation: 'scientific' 
});

console.log(formatter.format(1234567.89)); // Outputs: "1.23E8%"

notation: 'scientific' is used to represent large percentage amounts in a compact, scientific notation form.

Advanced Number Formatting Options

Beyond these basic features, NumberFormat offers advanced options like controlling the display of positive and negative numbers (sign display), setting minimum and maximum integer digits, compact display for large numbers, different rounding modes, and handling different numbering systems.

Let’s explore some use cases for advanced formatting:

Sign Display

let formatter = new Intl.NumberFormat('en-US', { 
  signDisplay: 'never' 
});

console.log(formatter.format(-1234)); // Outputs: "1,234"

This code uses the signDisplay: 'never' option, which means that the sign of the number (positive or negative) will not be displayed in the output.

Unit Display

let formatter = new Intl.NumberFormat('en-US', { 
  style: 'unit',
  unit: 'kilometer-per-hour' 
});

console.log(formatter.format(1234)); // Outputs: "1,234 km/h"

This code uses the style: 'unit' and unit: 'kilometer-per-hour' options to display the number as a speed in kilometers per hour.

Custom Decimal and Grouping Separators

et formatter = new Intl.NumberFormat('fr-FR', { 
  minimumFractionDigits: 2,
  maximumFractionDigits: 2 
});

console.log(formatter.format(1234.567)); // Outputs: "1 234,57"

This code formats the number according to the fr-FR (French) locale, which uses a space as a group separator and a comma as a decimal separator. It also ensures that there are exactly two digits after the decimal point.

Using Minimum Integer Digits

let formatter = new Intl.NumberFormat('en-US', { 
  minimumIntegerDigits: 5 
});

console.log(formatter.format(123)); // Outputs: "00,123"

This code uses the minimumIntegerDigits: 5 option, which ensures that the integer part of the formatted string has at least five digits, padding with zeroes if necessary.

Further Reading

Conclusion

In conclusion, the Intl.NumberFormat API is a powerful tool for number formatting that offers vast options to cater to different use cases and locales. Remember, internationalization is a key aspect of global application design, and proper number formatting forms a critical part of this process. Explore the Intl library’s documentation for more details and options. Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *