Docs
9.3-Internationalization-Intl
9.3 Internationalization (Intl)
Overview
The Intl object is the namespace for the ECMAScript Internationalization API, which provides language-sensitive string comparison, number formatting, date and time formatting, and more. It enables developers to create applications that adapt to different locales and cultural conventions.
Learning Objectives
- •Format numbers according to locale conventions
- •Format dates and times for different regions
- •Compare and sort strings in locale-aware manner
- •Format lists and relative times
- •Work with plural rules and display names
Core Concepts
Locale Identifiers
Locales are identified using BCP 47 language tags:
// Language only
'en'; // English
'zh'; // Chinese
// Language + Region
'en-US'; // English (United States)
'en-GB'; // English (United Kingdom)
'zh-CN'; // Chinese (China)
'zh-TW'; // Chinese (Taiwan)
// Language + Script + Region
'zh-Hans-CN'; // Chinese (Simplified, China)
'zh-Hant-TW'; // Chinese (Traditional, Taiwan)
// With extensions
'en-US-u-ca-buddhist'; // English with Buddhist calendar
Intl.NumberFormat
Basic Number Formatting
const number = 1234567.89;
// Different locales
console.log(new Intl.NumberFormat('en-US').format(number)); // 1,234,567.89
console.log(new Intl.NumberFormat('de-DE').format(number)); // 1.234.567,89
console.log(new Intl.NumberFormat('ar-EG').format(number)); // ١٬٢٣٤٬٥٦٧٫٨٩
console.log(new Intl.NumberFormat('ja-JP').format(number)); // 1,234,567.89
Currency Formatting
const amount = 1234.56;
const usd = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(amount); // $1,234.56
const eur = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR',
}).format(amount); // 1.234,56 €
const jpy = new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY',
}).format(amount); // ¥1,235 (no decimals for yen)
// Currency display options
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencyDisplay: 'code', // USD 1,234.56
}).format(amount);
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencyDisplay: 'name', // 1,234.56 US dollars
}).format(amount);
Percentage Formatting
const ratio = 0.7523;
new Intl.NumberFormat('en-US', {
style: 'percent',
}).format(ratio); // 75%
new Intl.NumberFormat('en-US', {
style: 'percent',
minimumFractionDigits: 2,
}).format(ratio); // 75.23%
Unit Formatting
const speed = 60;
const temp = 37.5;
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'mile-per-hour',
}).format(speed); // 60 mph
new Intl.NumberFormat('de-DE', {
style: 'unit',
unit: 'kilometer-per-hour',
}).format(speed); // 60 km/h
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius',
}).format(temp); // 37.5°C
Number Formatting Options
// Significant digits
new Intl.NumberFormat('en-US', {
maximumSignificantDigits: 3,
}).format(1234567); // 1,230,000
// Decimal places
new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 4,
}).format(1.5); // 1.50
// Notation
new Intl.NumberFormat('en-US', {
notation: 'scientific',
}).format(1234567); // 1.235E6
new Intl.NumberFormat('en-US', {
notation: 'compact',
compactDisplay: 'short',
}).format(1234567); // 1.2M
new Intl.NumberFormat('en-US', {
notation: 'compact',
compactDisplay: 'long',
}).format(1234567); // 1.2 million
Intl.DateTimeFormat
Basic Date Formatting
const date = new Date('2024-03-15T14:30:00');
// Different locales
console.log(new Intl.DateTimeFormat('en-US').format(date)); // 3/15/2024
console.log(new Intl.DateTimeFormat('en-GB').format(date)); // 15/03/2024
console.log(new Intl.DateTimeFormat('de-DE').format(date)); // 15.3.2024
console.log(new Intl.DateTimeFormat('ja-JP').format(date)); // 2024/3/15
Date Style Options
const date = new Date('2024-03-15T14:30:00');
new Intl.DateTimeFormat('en-US', { dateStyle: 'full' }).format(date);
// Friday, March 15, 2024
new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }).format(date);
// March 15, 2024
new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }).format(date);
// Mar 15, 2024
new Intl.DateTimeFormat('en-US', { dateStyle: 'short' }).format(date);
// 3/15/24
Time Formatting
const date = new Date('2024-03-15T14:30:45');
new Intl.DateTimeFormat('en-US', {
timeStyle: 'full',
timeZone: 'America/New_York',
}).format(date);
// 10:30:45 AM Eastern Daylight Time
new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true,
}).format(date);
// 2:30 PM
Custom Date/Time Components
const date = new Date('2024-03-15T14:30:00');
new Intl.DateTimeFormat('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short',
}).format(date);
// Friday, March 15, 2024, 02:30 PM EDT
Format Parts
const formatter = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
const parts = formatter.formatToParts(new Date('2024-03-15'));
// [
// { type: 'month', value: 'March' },
// { type: 'literal', value: ' ' },
// { type: 'day', value: '15' },
// { type: 'literal', value: ', ' },
// { type: 'year', value: '2024' }
// ]
Intl.RelativeTimeFormat
Relative Time Formatting
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
rtf.format(-1, 'day'); // yesterday
rtf.format(1, 'day'); // tomorrow
rtf.format(-2, 'day'); // 2 days ago
rtf.format(2, 'day'); // in 2 days
rtf.format(-1, 'week'); // last week
rtf.format(1, 'month'); // next month
rtf.format(-3, 'year'); // 3 years ago
// Always show numbers
const rtfNumeric = new Intl.RelativeTimeFormat('en', { numeric: 'always' });
rtfNumeric.format(-1, 'day'); // 1 day ago
Different Styles
// Long (default)
new Intl.RelativeTimeFormat('en', { style: 'long' }).format(-5, 'minute'); // 5 minutes ago
// Short
new Intl.RelativeTimeFormat('en', { style: 'short' }).format(-5, 'minute'); // 5 min. ago
// Narrow
new Intl.RelativeTimeFormat('en', { style: 'narrow' }).format(-5, 'minute'); // 5 min. ago
Intl.ListFormat
Formatting Lists
const items = ['Apple', 'Banana', 'Orange'];
// Conjunction (and)
new Intl.ListFormat('en', { style: 'long', type: 'conjunction' }).format(items); // Apple, Banana, and Orange
// Disjunction (or)
new Intl.ListFormat('en', { style: 'long', type: 'disjunction' }).format(items); // Apple, Banana, or Orange
// Unit (no conjunction)
new Intl.ListFormat('en', { style: 'narrow', type: 'unit' }).format([
'5 feet',
'10 inches',
]); // 5 feet 10 inches
// Different locales
new Intl.ListFormat('de', { type: 'conjunction' }).format(items); // Apple, Banana und Orange
Intl.PluralRules
Plural Categories
const pr = new Intl.PluralRules('en');
pr.select(0); // 'other'
pr.select(1); // 'one'
pr.select(2); // 'other'
pr.select(21); // 'other'
// Russian has more categories
const prRu = new Intl.PluralRules('ru');
prRu.select(1); // 'one'
prRu.select(2); // 'few'
prRu.select(5); // 'many'
Practical Usage
function pluralize(count, forms) {
const pr = new Intl.PluralRules('en');
return forms[pr.select(count)];
}
const apple = {
one: 'apple',
other: 'apples',
};
console.log(`1 ${pluralize(1, apple)}`); // 1 apple
console.log(`5 ${pluralize(5, apple)}`); // 5 apples
Intl.Collator
String Comparison
const collator = new Intl.Collator('en');
// Compare strings
collator.compare('a', 'b'); // -1 (a before b)
collator.compare('b', 'a'); // 1 (b after a)
collator.compare('a', 'a'); // 0 (equal)
// Sorting
const words = ['réservé', 'Premier', 'communiqué', 'café'];
words.sort(new Intl.Collator('fr').compare);
// ['café', 'communiqué', 'Premier', 'réservé']
Collation Options
// Case-insensitive
const caseInsensitive = new Intl.Collator('en', { sensitivity: 'base' });
caseInsensitive.compare('a', 'A'); // 0 (equal)
// Numeric sorting
const numeric = new Intl.Collator('en', { numeric: true });
['file10', 'file2', 'file1'].sort(numeric.compare);
// ['file1', 'file2', 'file10']
// Ignore punctuation
const ignorePunct = new Intl.Collator('en', { ignorePunctuation: true });
ignorePunct.compare("can't", 'cant'); // 0
Intl.DisplayNames
Display Names for Regions, Languages, etc.
// Region names
const regionNames = new Intl.DisplayNames(['en'], { type: 'region' });
regionNames.of('US'); // United States
regionNames.of('DE'); // Germany
regionNames.of('JP'); // Japan
// Language names
const langNames = new Intl.DisplayNames(['en'], { type: 'language' });
langNames.of('en'); // English
langNames.of('de'); // German
langNames.of('ja'); // Japanese
// Currency names
const currencyNames = new Intl.DisplayNames(['en'], { type: 'currency' });
currencyNames.of('USD'); // US Dollar
currencyNames.of('EUR'); // Euro
// Script names
const scriptNames = new Intl.DisplayNames(['en'], { type: 'script' });
scriptNames.of('Latn'); // Latin
scriptNames.of('Arab'); // Arabic
Intl.Segmenter (ES2022)
Text Segmentation
// Word segmentation
const wordSegmenter = new Intl.Segmenter('en', { granularity: 'word' });
const text = 'Hello, world!';
const segments = [...wordSegmenter.segment(text)];
// Segments: 'Hello', ',', ' ', 'world', '!'
// Sentence segmentation
const sentenceSegmenter = new Intl.Segmenter('en', { granularity: 'sentence' });
const paragraph = 'Hello! How are you? I am fine.';
const sentences = [...sentenceSegmenter.segment(paragraph)];
// Character segmentation (grapheme clusters)
const graphemeSegmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
const emoji = '👨👩👧👦';
const graphemes = [...graphemeSegmenter.segment(emoji)];
// 1 grapheme (even though multiple code points)
Locale-Aware Best Practices
User's Preferred Locale
// Get browser's preferred locales
const userLocales = navigator.languages; // ['en-US', 'en', 'es']
// Use first available match
const formatter = new Intl.DateTimeFormat(userLocales);
Fallback Chain
function formatWithFallback(value, locales, options) {
try {
return new Intl.NumberFormat(locales, options).format(value);
} catch (e) {
// Fallback to default locale
return new Intl.NumberFormat('en-US', options).format(value);
}
}
Summary
| Formatter | Purpose | Example |
|---|---|---|
| NumberFormat | Number, currency, percent | $1,234.56 |
| DateTimeFormat | Dates and times | March 15, 2024 |
| RelativeTimeFormat | Relative times | 2 days ago |
| ListFormat | Lists | A, B, and C |
| PluralRules | Pluralization | 1 apple, 2 apples |
| Collator | String comparison | Locale-aware sorting |
| DisplayNames | Locale display names | United States |
| Segmenter | Text segmentation | Word/sentence boundaries |