Intl.NumberFormat: примеры (JAVASCRIPT)

Форматирование чисел через Intl.NumberFormat в JavaScript
Раздел: Интернационазация, Числа
Intl.NumberFormat(locales (string, Array), options (object)): Intl.NumberFormat

Базовая информация о Intl.NumberFormat

Конструктор Intl.NumberFormat создает объекты, позволяющие форматировать числа с учетом языка и региональных настроек. Эта функциональность применяется для отображения чисел, валют, процентов и единиц измерения в формате, понятном пользователю из определенной локали.

Функция используется, когда необходимо представить числовые данные в локализованном формате: суммы денег, проценты, большие числа с разделителями разрядов или числа в различных системах счисления.

Синтаксис: new Intl.NumberFormat([locales[, options]]).

Параметр locales может быть строкой с тегом языка BCP 47 или массивом таких строк. Он определяет язык и региональные настройки для форматирования. Если параметр не указан, используется локаль по умолчанию среды выполнения.

Параметр options — объект, настраивающий поведение форматирования. Основные свойства:

  • style: определяет стиль форматирования. Возможные значения: 'decimal' (по умолчанию), 'currency', 'percent', 'unit'.
  • currency: код валюты для стиля 'currency' (например, 'USD', 'EUR').
  • currencyDisplay: как отображать валюту. Варианты: 'symbol' (по умолчанию), 'narrowSymbol', 'code', 'name'.
  • useGrouping: использовать ли разделитель групп разрядов (например, запятая для тысяч).
  • minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits: контроль количества цифр в целой и дробной частях.
  • notation: обозначение числа. Варианты: 'standard' (по умолчанию), 'scientific', 'engineering', 'compact'.
  • compactDisplay: отображение для компактной нотации ('short' или 'long').
  • signDisplay: когда показывать знак числа. Варианты: 'auto' (по умолчанию), 'always', 'never', 'exceptZero'.
  • unit, unitDisplay: единица измерения и ее отображение для стиля 'unit'.
  • numberingSystem: система счисления (например, 'arab', 'latn').

Метод format(number) возвращает строку с отформатированным числом. Объект также предоставляет методы formatToParts() и resolvedOptions().

Основные примеры использования

Простое форматирование числа для разных локалей:

console.log(new Intl.NumberFormat('ru-RU').format(1234567.89));
1 234 567,89

Форматирование валюты:

console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(1234.56));
$1,234.56

Процентный формат:

console.log(new Intl.NumberFormat('fr-FR', { style: 'percent' }).format(0.123));
12,3 %

Форматирование с указанием единиц измерения:

console.log(new Intl.NumberFormat('en-GB', { style: 'unit', unit: 'kilometer-per-hour', unitDisplay: 'short' }).format(100));
100 km/h

Компактная нотация:

console.log(new Intl.NumberFormat('ru', { notation: 'compact', compactDisplay: 'long' }).format(1_200_000));
1,2 миллиона

Настройка отображения знака:

console.log(new Intl.NumberFormat('en', { signDisplay: 'always' }).format(42));
+42

Похожие функции в JavaScript

Для форматирования чисел в JavaScript также могут применяться следующие подходы:

  • Number.prototype.toLocaleString(): метод, который использует тот же движок, что и Intl.NumberFormat. Он удобен для быстрого форматирования одного числа. Предпочтительнее использовать, когда не требуется многократное форматирование с одинаковыми настройками, так как создает новый объект форматирования каждый раз.
  • Number.prototype.toFixed(): возвращает строку с фиксированным количеством знаков после запятой, но без учета локали. Используется для простого округления и представления в десятичном формате.
  • Number.prototype.toString(): преобразует число в строку без какого-либо форматирования. Может использоваться с аргументом для вывода в системах счисления от 2 до 36.

Для сложного, производительного и многократного форматирования Intl.NumberFormat является оптимальным выбором, так как объект форматирования создается один раз и может использоваться многократно.

Альтернативы в других языках программирования

В других языках существуют аналогичные инструменты для интернационализации чисел.

PHP: класс NumberFormatter из расширения intl.

$fmt = new NumberFormatter('ru_RU', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.56, 'RUB');
1 234,56 ₽

Python: модуль locale или сторонние библиотеки, например babel.

import locale
locale.setlocale(locale.LC_ALL, 'ru_RU.UTF-8')
print(locale.currency(1234.56, grouping=True))
1 234,56 руб.

C#: использование ToString с указанием культуры или string.Format с провайдером формата.

double value = 1234.56;
Console.WriteLine(value.ToString("C", CultureInfo.GetCultureInfo("ru-RU")));
1 234,56 ₽

MySQL: функция FORMAT() для базового форматирования с разделителями, но без учета валют и сложных локалей.

SELECT FORMAT(1234567.89, 2, 'ru_RU');
1 234 567,89

Основное отличие JavaScript Intl.NumberFormat — его глубокая интеграция со стандартом ECMAScript и поддержка современных браузеров без необходимости установки дополнительных библиотек.

Типичные ошибки

Использование неверного кода валюты для заданной локали. Результат может быть неожиданным или привести к ошибке.

try {
  let formatter = new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'XYZ' });
  console.log(formatter.format(100));
} catch (e) {
  console.log(e.message);
}
RangeError: Invalid currency code : XYZ

Игнорирование того, что maximumFractionDigits не может быть меньше minimumFractionDigits.

try {
  let formatter = new Intl.NumberFormat('en', { minimumFractionDigits: 3, maximumFractionDigits: 2 });
} catch (e) {
  console.log(e.message);
}
RangeError: minimumFractionDigits value is out of range.

Непонимание того, что метод format возвращает строку, и дальнейшие математические операции требуют обратного преобразования.

let formatter = new Intl.NumberFormat('en-US');
let result = formatter.format(1000) + 500;
console.log(result);
1,000500

Забывают, что объект форматирования кэширует настройки локали и опций при создании. Изменение объекта опций после создания не повлияет на форматирование.

Изменения в последних версиях

В спецификации ECMAScript Internationalization API (ECMA-402) постоянно добавляются новые возможности. Например, в более поздних версиях были введены:

  • Свойство signDisplay для контроля отображения знака числа.
  • Расширенные значения для currencyDisplay, такие как 'narrowSymbol'.
  • Поддержка форматирования единиц измерения (style: 'unit').
  • Опции compactDisplay для компактной нотации.
  • Возможность задавать систему счисления через numberingSystem.
  • Метод formatRange() для форматирования диапазонов чисел, добавленный в ES2024.

Рекомендуется проверять таблицу совместимости Can I Use или MDN для актуальной информации о поддержке в браузерах и средах выполнения.

Расширенные и специальные примеры

Использование formatToParts для получения структурированных данных о форматировании. Это полезно для кастомного отображения.

Пример javascript
let formatter = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
let parts = formatter.formatToParts(1234.56);
console.log(parts);
[
  { type: 'integer', value: '1' },
  { type: 'group', value: '.' },
  { type: 'integer', value: '234' },
  { type: 'decimal', value: ',' },
  { type: 'fraction', value: '56' },
  { type: 'literal', value: ' ' },
  { type: 'currency', value: '€' }
]

Форматирование с использованием нескольких локалей с fallback. Первая поддерживаемая локаль будет использована.

Пример javascript
let formatter = new Intl.NumberFormat(['ban-ID', 'en-US']);
console.log(formatter.resolvedOptions().locale);
console.log(formatter.format(9876.54));
en-US
9,876.54

Настройка форматирования для финансовых отчетов, где отрицательные числа могут отображаться в скобках.

Пример javascript
let formatter = new Intl.NumberFormat('en-US', { 
  style: 'currency', 
  currency: 'USD', 
  currencySign: 'accounting', 
  signDisplay: 'always' 
});
console.log(formatter.format(-1234.56));
($1,234.56)

Форматирование больших чисел в компактной нотации для социальных сетей.

Пример javascript
let formatter = new Intl.NumberFormat('en', { notation: 'compact', compactDisplay: 'short' });
console.log(formatter.format(15_600_000));
console.log(formatter.format(1_200_000_000));
15.6M
1.2B

Использование нестандартных систем счисления, например, арабской индийской.

Пример javascript
let formatter = new Intl.NumberFormat('en-US', { numberingSystem: 'arab' });
console.log(formatter.format(1234567890));
۱۲۳٬۴۵۶٬۷۸۹۰

Комбинирование стиля 'unit' с другими опциями, такими как signDisplay.

Пример javascript
let formatter = new Intl.NumberFormat('ru', { 
  style: 'unit', 
  unit: 'celsius',
  unitDisplay: 'long',
  signDisplay: 'always'
});
console.log(formatter.format(-5));
-5 градуса Цельсия

JS Intl.NumberFormat function comments

En
Intl.NumberFormat Formats numbers according to locale