Как форматировать числа с разделителями тысяч

Используйте JavaScript для отображения больших чисел с разделителями, соответствующими локали пользователя

Введение

Большие числа сложно читать без визуального разделения. Число 1234567 требует внимательного подсчёта, чтобы понять, миллион это или десять миллионов. Если добавить разделители, получится 1,234,567, и сразу видно, что это примерно миллион.

В разных странах для разделения групп цифр используют разные символы. В США ставят запятые, в Германии — точки, а во Франции — пробелы. Если вы показываете числа в приложении для пользователей со всего мира, их нужно форматировать в соответствии с ожиданиями каждого пользователя.

В JavaScript есть API Intl.NumberFormat, который делает это автоматически. В этом уроке объясняется, как работают разделители тысяч, почему они различаются в разных странах и как правильно форматировать числа для любого языка или региона.

Что такое разделители тысяч

Разделитель тысяч — это символ, который вставляется между группами цифр, чтобы большие числа было проще читать. В большинстве стран цифры группируют по три справа налево. Число 1234567 превращается в 1,234,567 с запятыми в качестве разделителей.

Термин «разделитель тысяч» появился из-за самого частого случая, когда разделители ставят после каждых трёх цифр. Но этот же принцип работает и для других группировок — сотен тысяч, миллионов или миллиардов.

Без разделителей цифры сливаются, и приходится внимательно пересчитывать. С разделителями взгляд сразу определяет порядок числа. Такое визуальное разделение снижает количество ошибок и помогает быстрее воспринимать информацию.

Почему разделители тысяч различаются в разных странах

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

В англоязычных странах, таких как США, Великобритания и Австралия, в качестве разделителя тысяч используется запятая. Миллион записывается как 1,000,000.

Во многих европейских странах, включая Германию, Италию, Испанию и Португалию, для разделения тысяч используется точка. То же число выглядит так: 1.000.000.

Во Франции и во многих франкоязычных регионах для разделения тысяч используется пробел. Число записывается как 1 000 000.

В Швейцарии для разделения тысяч используют апостроф. Число выглядит так: 1'000'000.

В некоторых странах, например в Индии, используются другие схемы группировки. В индийской системе первые три цифры отделяются, а затем цифры группируются по две. Миллион записывается как 10,00,000 по системе лакхов.

Если вы жёстко задаёте определённый символ-разделитель, вы предполагаете, что все пользователи придерживаются одной и той же схемы. Это усложняет работу с приложением для людей из других регионов.

Как использовать Intl.NumberFormat для добавления разделителей тысяч

Конструктор Intl.NumberFormat создаёт форматтер чисел, который применяет правила, характерные для выбранной локали. Передайте идентификатор локали первым аргументом, затем вызовите метод format() с нужным числом.

const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(1234567));
// Output: "1,234,567"

Так создаётся форматтер для американского английского, где в качестве разделителя тысяч используется запятая. Метод format() преобразует число в строку с нужными разделителями.

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

const usFormatter = new Intl.NumberFormat('en-US');
console.log(usFormatter.format(1234567));
// Output: "1,234,567"

const deFormatter = new Intl.NumberFormat('de-DE');
console.log(deFormatter.format(1234567));
// Output: "1.234.567"

const frFormatter = new Intl.NumberFormat('fr-FR');
console.log(frFormatter.format(1234567));
// Output: "1 234 567"

Каждый форматтер применяет правила, принятые в своей локали. Немецкий форматтер использует точки, французский — пробелы, а американский — запятые. Не нужно знать, какой символ используется в каждой локали — API автоматически обрабатывает эти детали.

Форматирование чисел для локали пользователя

Вместо того чтобы жёстко задавать определённую локаль, можно использовать предпочитаемый язык пользователя из браузера. Свойство navigator.language возвращает основной языковой приоритет пользователя.

const userLocale = navigator.language;
const formatter = new Intl.NumberFormat(userLocale);

console.log(formatter.format(1234567));
// Output varies by user's locale
// For en-US: "1,234,567"
// For de-DE: "1.234.567"
// For fr-FR: "1 234 567"

Такой подход отображает числа так, как ожидает каждый пользователь, без необходимости вручную выбирать локаль. Браузер предоставляет языковые предпочтения, а Intl API применяет соответствующие правила форматирования.

Также можно передать весь массив предпочитаемых языков, чтобы включить механизм резервирования (fallback).

const formatter = new Intl.NumberFormat(navigator.languages);
console.log(formatter.format(1234567));

API использует первую поддерживаемую локаль из массива. Это обеспечивает более корректную обработку, если основной язык пользователя недоступен.

Как работает группировка по умолчанию

По умолчанию Intl.NumberFormat добавляет разделители тысяч ко всем достаточно большим числам, чтобы группировка была полезной. Обычно числа с четырьмя и более знаками получают разделители, хотя это зависит от локали.

const formatter = new Intl.NumberFormat('en-US');

console.log(formatter.format(123));
// Output: "123"

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

console.log(formatter.format(12345));
// Output: "12,345"

console.log(formatter.format(123456));
// Output: "123,456"

Маленькие числа, такие как 123, не нуждаются в разделителях и отображаются без них. Числа, начинающиеся с 1234, получают разделители, так как группировка улучшает читаемость.

API автоматически определяет, когда разделители полезны, исходя из правил локали. Не нужно вручную проверять разрядность каждого числа перед форматированием.

Форматирование десятичных чисел с разделителями тысяч

API Intl.NumberFormat обрабатывает как целую, так и дробную части чисел. Разделители тысяч появляются в целой части, а десятичная точка и дробные разряды оформляются по правилам выбранной локали.

const usFormatter = new Intl.NumberFormat('en-US');
console.log(usFormatter.format(1234567.89));
// Output: "1,234,567.89"

const deFormatter = new Intl.NumberFormat('de-DE');
console.log(deFormatter.format(1234567.89));
// Output: "1.234.567,89"

Обратите внимание, что в немецком формате оба правила меняются местами. Точки используются как разделители тысяч в целой части, а запятая — как десятичный разделитель для дробной части. Intl API корректно учитывает оба аспекта в зависимости от локали.

Работа с очень большими числами

Разделители тысяч становятся всё важнее по мере увеличения числа. Без разделителей числа с семью, восемью или девятью знаками практически невозможно быстро и точно прочитать.

const formatter = new Intl.NumberFormat('en-US');

console.log(formatter.format(1234567890));
// Output: "1,234,567,890"

console.log(formatter.format(9876543210));
// Output: "9,876,543,210"

Форматтер вставляет разделители через каждые три цифры, делая даже миллиардные числа легко читаемыми. Такое автоматическое группирование работает для чисел любого размера и не требует вручную рассчитывать позиции разделителей.

Повторное использование форматтеров для повышения производительности

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

const formatter = new Intl.NumberFormat('en-US');

const numbers = [1234, 5678, 91011, 121314];

numbers.forEach(number => {
  console.log(formatter.format(number));
});
// Output:
// "1,234"
// "5,678"
// "91,011"
// "121,314"

Такой подход эффективнее, чем создавать новый форматтер для каждого числа. Разница в производительности становится заметной при форматировании массивов из сотен или тысяч значений.

Форматирование чисел в шаблонах

Вы можете использовать Intl.NumberFormat везде, где отображаете числа пользователям. Это может быть вставка отформатированных чисел в HTML-шаблоны, вывод значений в таблицах или показ статистики на дашбордах.

const formatter = new Intl.NumberFormat(navigator.language);

const totalUsers = 1234567;
const activeUsers = 891234;

document.getElementById('total-users').textContent = formatter.format(totalUsers);
document.getElementById('active-users').textContent = formatter.format(activeUsers);

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