В разных культурах используются различные подходы к отображению чисел. Например, в одних культурах (в частности, в США, Великобритании) в качестве разделителя целой и дробной части применяется точка, а в других культурах - запятая. Аналогично разделителем между разрядами может служить как точка, так и запятая. И объект Intl.NumberFormat позволяет нам локализовать числительные под нужную культуру.
Конструктор Intl.NumberFormat может принимать два параметра:
Intl.NumberFormat([locales[, options]])
Параметр locales представляет код языка в формате BCP 47 или набор языковых кодов.
Параметр options представляет дополнительный набор опций:
localeMatcher: алгоритм поиска соответствий. Может принимать два значения: "lookup" и "best fit".
Значение по умолчанию - "best fit".
compactDisplay: применяется, если параметр notation равен "compact".
Возможные значения: "long" и "short" (значение по умолчанию)
currency: задает валюту, которая применяется для форматирования.
В качестве значения принимает код валюты в формате ISO 4217, например, "USD" (доллар США), "EUR" (евро) и т.д. Этот параметр необходимо обязательно указать,
если параметр style имеет значение "currency".
currencyDisplay: указывает, как отображать валюту. Возможные значения:
"symbol": применяется символ валюты (например, € для евро). Значение по умолчанию
"narrowSymbol": применяется сокращенное обозначение валюты (например, "$100" вместо "US$100")
"code": применяется код валюты
"name": применяется локализованное название валюты (например, "dollar")
currencySign: знак перед числительным, которое представляет валюту. Может принимать значения "standard"
(значение по умолчанию) и "accounting"
notation: задает тип форматирования. Возможные значения:
"standard": применяется для форматирования обычных чисел. Значение по умолчанию
"scientific": возвращает порядок величины для форматируемого числа
"engineering": возвращает значение в экспоненциальной нотации
"compact": для представления экспоненциальной записи применяется строка
numberingSystem: числовая система. Возможные значения: "arab", "arabext", " bali", "beng", "deva", "fullwide", " gujr", "guru", "hanidec", "khmr", " knda", "laoo", "latn", "limb", "mlym", " mong", "mymr", "orya", "tamldec", " telu", "thai", "tibt"
signDisplay: указывает, нужно ли отображать знак перед числом. Возможные значения:
"auto": знак отображается только для отрицательных чисел. Значение по умолчанию
"never": знак никогда не отображается
"always": знак отображается всегда
"exceptZero": знак отображается для всех чисел, кроме нуля
style: тип форматирования. Возможные значения:
"decimal": для форматирования обычных чисел. Значение по умолчанию
"currency": для форматирования валюты
"percent": для форматирования процентов
"unit": для форматирования единиц измерения
unit: устанавливает единицу измерения. Применяемые единицы измерения можно найти в следующей таблице.
unitDisplay: тип отображения единиц измерения. Возможные значения:
"long": полная форма (например, 16 litres)
"short": сокращенная форма (например, 16 l). Значение по умолчанию
"narrow": сжатая форма (например, 16l)
useGrouping: указывает, надо ли использовать разделитель для разрядов числа. Может принимать значения true
(использовать разделители - значение по умолчанию) и false (не использовать разделители)
minimumIntegerDigits: минимальное количество цифр в числе. Возможные значения: от 1 (значение по умолчанию) до 21
minimumFractionDigits: минимальное количество цифр в дробной части числа. Возможные значения: от 0 (значение по умолчанию) до 20
maximumFractionDigits: максимальное количество цифр в дробной части числа. Возможные значения: от 0 до 20
minimumSignificantDigits: минимальное количество цифр в целой части числа. Возможные значения: от 1 (значение по умолчанию) до 21
maximumSignificantDigits: максимальное количество цифр в целой части числа. Возможные значения: от 1 (значение по умолчанию) до 21
Для форматирования числа объект Intl.NumberFormat предоставляет метод format(), в который передается форматируемое число и который возвращает отформатированное число в виде строки.
Локализуем число 5500,67 на разные языки:
const amount = 5500.67;
const en = new Intl.NumberFormat("en").format(amount);
const ru = new Intl.NumberFormat("ru").format(amount);
const de = new Intl.NumberFormat("de").format(amount);
console.log(en); // 5,500.67
console.log(ru); // 5 500,67
console.log(de); // 5.500,67
По умолчанию для форматирования чисел применяется параметр {style: "decimal"}. Также мы могли бы его явно применить:
const amount = 5500.67;
const ru = new Intl.NumberFormat("ru", {style: "decimal"}).format(amount);
// то же самое, что и
// const ru = new Intl.NumberFormat("ru").format(amount);
console.log(ru); // 5 500,67
В разных культурах может отличаться написание процентов. Для локализации процентов применяется значение
const value = 0.851;
const en = new Intl.NumberFormat("en", {style: "percent"}).format(value);
const ru = new Intl.NumberFormat("ru", {style: "percent"}).format(value);
const tr = new Intl.NumberFormat("tr", {style: "percent"}).format(value);
console.log(en); // 85%
console.log(ru); // 85 %
console.log(tr); // %85
Однако в примере выше мы видим, что теряется дробная часть. Чтобы исправить положение, мы можем использовать параметр minimumFractionDigits, который задает количество знаков в дробной части:
const value = 0.851;
const en = new Intl.NumberFormat("en", {style: "percent", minimumFractionDigits: 2}).format(value);
const ru = new Intl.NumberFormat("ru", {style: "percent", minimumFractionDigits: 2}).format(value);
console.log(en); // 85.10%
console.log(ru); // 85,10 %
Для форматирования валюты применяется параметр style: "currency", при этом также надо указать параметр currency, которому передается код валюты:
const value = 85.1;
const en = new Intl.NumberFormat("en", {style: "currency", currency: "USD"}).format(value);
const ru = new Intl.NumberFormat("ru", {style: "currency", currency: "USD"}).format(value);
const tr = new Intl.NumberFormat("tr", {style: "currency", currency: "USD"}).format(value);
console.log(en); // $85.10
console.log(ru); // 85,10 $
console.log(tr); // $85,10
Вывод нескольких валют:
const value = 85.1;
const usd = new Intl.NumberFormat("ru", {style: "currency", currency: "USD"}).format(value);
const euro = new Intl.NumberFormat("ru", {style: "currency", currency: "EUR"}).format(value);
const rub = new Intl.NumberFormat("ru", {style: "currency", currency: "RUB"}).format(value);
console.log(usd); // 85,10 $
console.log(euro); // 85,10 €
console.log(rub); // 85,10 ₽
По умолчанию выводится символ валюты, однако значение currencyDisplay: "name" позволяет вывести локализованное название валюты:
const value = 85;
const usd = new Intl.NumberFormat("ru", {style: "currency", currency: "USD", currencyDisplay: "name", minimumFractionDigits: 0}).format(value);
const euro = new Intl.NumberFormat("ru", {style: "currency", currency: "EUR", currencyDisplay: "name"}).format(value);
const rub = new Intl.NumberFormat("ru", {style: "currency", currency: "RUB", currencyDisplay: "name"}).format(value);
console.log(usd); // 85 долларов США
console.log(euro); // 85,00 евро
console.log(rub); // 85,00 российского рубля
Для форматирования единиц измерения применяется значение style: "unit". При этом также необходимо указать название единицы измерения с
помощью параметра unit:
const value = 85;
const en = new Intl.NumberFormat("en", {style: "unit", unit: "liter"}).format(value);
const ru = new Intl.NumberFormat("ru", {style: "unit", unit: "liter"}).format(value);
const zh = new Intl.NumberFormat("zh", {style: "unit", unit: "liter"}).format(value);
console.log(en); // 85 L
console.log(ru); // 85 л
console.log(zh); // 85升
По умолчанию применяет сокращенная форма наименования валюты. С помощью значения unitDisplay: "long" можно задать вывод полного наименования:
const value = 85;
const longLiter = new Intl.NumberFormat("ru", {style: "unit", unit: "liter", unitDisplay: "long"}).format(value);
const shortLiter = new Intl.NumberFormat("ru", {style: "unit", unit: "liter", unitDisplay: "short"}).format(value);
console.log(longLiter); // 85 литров
console.log(shortLiter); // 85 л
Еще несколько примеров с форматированием разных единиц измерения:
const value = 85;
const kilobyte = new Intl.NumberFormat("ru", {style: "unit", unit: "kilobyte", unitDisplay: "long"}).format(value);
const meter = new Intl.NumberFormat("ru", {style: "unit", unit: "meter", unitDisplay: "long"}).format(value);
const gram = new Intl.NumberFormat("ru", {style: "unit", unit: "gram", unitDisplay: "long"}).format(value);
console.log(kilobyte); // 85 килобайт
console.log(meter); // 85 метров
console.log(gram); // 85 грамм
Стоит отметить, что у типа Number есть метод toLocaleString(), который принимает локаль и который локализует в эту локаль число:
const num = 1007.56;
console.log(num.toLocaleString("en")); // 1,007.56
console.log(num.toLocaleString("de")); // 1.007,56
console.log(num.toLocaleString("ru")); // 1 007,56