New Intl APIs in JavaScript
Learn how to use the new Intl object to format data into a specific locale
The Intl
object is available in the global scope and is used for formatting strings, numbers, and date and time in the locale-specific format. It does the work of internationalizing information displayed to the user.
A quick tip before we start: Use Bit to share and collaborate on your JS utility functions with your team or with the entire open-source community. Make your projects truly modular by versioning and collaborating on single components separately — with absolutely zero overhead.
Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes.
The JavaScript developers don’t have to ship KBs of locale-specific data in the main bundles. The Intl
object has various constructors and methods that take in locale object as one of the parameters and format data as required. Here’s how the Intl
global object looks like:
The Collator
, DateTimeFormat
, ListFormat
, NumberFormat
, PluralRules
, RelativeTimeFormat
are the constructors in the Intl
namespace. They take in two arguments — locales and options. The locale argument must be a string in BCP 47 language tag or an array of such strings. If you’re interested in knowing more about the BCP 47 language tag, here’s an excerpt from MDN:
A BCP 47 language tag defines a language and minimally contains a primary language code. In its most common form it can contain, in order: a language code, a script code, and a country or region code, all separated by hyphens. While the tag is not case sensitive, it is recommended to use title case for script code, upper case for country and region codes and lower case for everything else.
The default value of the locale argument is set to the locale of the runtime. Some of the examples of the locale are — en (English), hi (Hindi), ta-in (Tamil-India). The options argument is optional and its structure varies for different constructors. It is basically used for providing additional information for formatting.
In this article, we’re going to look at some of the new APIs that are added in the Intl
namespace. These new APIs were announced in Google I/O ‘19. Let’s get to these APIs in detail:
Intl.RelativeTimeFormat
The RelativeTimeFormat constructor is used to generate human-friendly phrases for timestamps. It converts the hard-to-read date object into its relative time string. Let’s see this in action:
Notice the first argument to the Intl.RelativeTimeFormat
constructor as en
. The possible values for the numeric key in the options object are always
and auto
— always
would format it in numbers as:
rtf.format(-1, 'month')
would result in 1 month ago.
If you’d want to display the relative bits in Tamil, you can do so in no time as:
The relative time strings yesterday, today, tomorrow, etc provide a better user experience! This is supported in Chrome 71 and FireFox 65.
Intl.ListFormat
The ListFormat constructor is used for joining strings using a disjunction or conjunction to form a meaningful phrase.
The format
method nicely concatenates the strings in the characters
array using and. If not for the ListFormat API, we would have to write utility functions to place commas and and at appropriate places. The Intl.ListFormat
API makes formatting strings a breeze!
We can customize the formatting experience by changing the default values in the options
object as:
The type disjunction
joins the strings using the or literal. Let’s check out the possible values for various properties on the options
object:
type: Possible values are conjunction
, disjunction
, and unit
. The conjunction
is the default value. The unit
type is used for unit-based lists like:
style: Possible values are long
and short
(or narrow
)
The ListFormat API is available in Chrome 72.
Intl.NumberFormat
JavaScript, unlike other high-level languages, provides flexibility with the data types of variables. An int
, float
, string
or an object
are all declared using var
(or let
and const
for block-scoping).
But how big can a number be?
123456789123456789 * 11 // Prints 1358024680358024700
The unit place of the result of the above operation cannot be 0! Looks like, we need to do something for the bigger numbers. And the good news is, we already have BigInt for handling large numbers. Let’s do the above operation using BigInt:
123456789123456789n * 11n // Prints 1358024680358024679n
This now looks correct!
The bigger numbers are difficult to read in one go. Here comes the Intl.NumerFormat API to help! It is used to format numbers by adding locale-specific numeric separators. Let’s see how this works:
Notice how numbers are formatted as per the specified locale. The numbers are formatted with commas for the en
locale and with spaces for the fr
locale.
We can also pass in the options
object to the constructor for customizing the formatting experience. Some of the properties available on the options
object are:
style: Possible values are decimal
, currency
, and percent
and the default value is decimal
currency: Currency code to be used for the currency style. Examples: USD, INR
currencyDisplay: Possible values are symbol
and code
and the default value is symbol
You can check all the properties in the options object here.
This is available in Chrome, FireFox, and Safari.
There’s one more exciting API in the list: Intl.DateTimeFormat
Intl.DateTimeFormat
The Intl.DateTimeFormat API is used for locale-specific date and time formatting. The new method formatRange
is now available on this API and it can be used as:
const df = new Intl.DateTimeFormat('en', {
year: 'numeric',
month: 'short',
day: 'numeric'
})
const startDate = new Date('01-06-2019')
const endDate = new Date('10-06-2019')
df.formatRange(startDate, endDate) // Prints Jun 1-10 2019
Notice how the formatRange
function groups together the dates of the same month. Please note: this function is available behind a flag in Chrome and will be shipped soon.
You can now remove that extra utility function from your bundle, which was just used for formatting date ranges!
There are many properties available in the options
object such as timeZone
, era
, year
, month
, day
, hour
, minute
, second
and many more.
Conclusion
We saw some of the new additions to the Intl object:
1. Intl.RelativeTimeFormat
API can be used to generate relative and human-friendly phrases for timestamps.
2. Intl.ListFormat
API can be used to construct phrases from the array elements using the conjunction
, disjunction,
and unit
types.
3. Intl.NumberFormat
can be used to format bigger numbers using locale-specific numeric literals.
4. The formatRange
method on the Intl.DateTimeFormat
API can be used to generate range strings for timestamps.