Как управлять отображением разделителей тысяч?

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

Введение

Когда вы форматируете число 123456, вы можете увидеть "123,456" с запятой в качестве разделителя тысяч или "123456" без какого-либо разделителя. Символ, который разделяет группы цифр, называется разделителем групп, а в англоязычных странах его часто называют разделителем тысяч.

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

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

Отключение разделителей групп с помощью useGrouping false

Установите useGrouping в false, чтобы убрать все разделители групп из форматированных чисел.

const formatter = new Intl.NumberFormat('en-US', {
  useGrouping: false
});

formatter.format(123456);
// "123456"

formatter.format(1234567.89);
// "1234567.89"

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

Это относится ко всем стилям чисел, включая валюту и единицы измерения.

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: false
}).format(1234567.89);
// "$1234567.89"

new Intl.NumberFormat('en-US', {
  style: 'unit',
  unit: 'kilometer',
  useGrouping: false
}).format(50000);
// "50000 km"

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

Включение разделителей групп с помощью useGrouping true

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

const formatter = new Intl.NumberFormat('en-US', {
  useGrouping: true
});

formatter.format(123456);
// "123,456"

formatter.format(1234567.89);
// "1,234,567.89"

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

Поскольку true используется по умолчанию, эти два форматтера работают одинаково.

new Intl.NumberFormat('en-US', { useGrouping: true });
new Intl.NumberFormat('en-US');

Оба форматтера добавляют разделители группировки в результат.

Как группировка отличается в разных локалях

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

new Intl.NumberFormat('en-US', {
  useGrouping: true
}).format(1234567);
// "1,234,567"

new Intl.NumberFormat('de-DE', {
  useGrouping: true
}).format(1234567);
// "1.234.567"

new Intl.NumberFormat('fr-FR', {
  useGrouping: true
}).format(1234567);
// "1 234 567"

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

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

new Intl.NumberFormat('en-IN', {
  useGrouping: true
}).format(1234567);
// "12,34,567"

Разделитель группировки появляется после трёх цифр справа, затем после каждых двух, в результате получается 12,34,567 вместо 1,234,567.

Если отключить группировку с помощью useGrouping: false, эти различия между локалями исчезают, потому что разделители не используются вообще.

new Intl.NumberFormat('en-IN', {
  useGrouping: false
}).format(1234567);
// "1234567"

Используйте строковые значения для расширенного управления группировкой

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

Значение "always" эквивалентно true и всегда показывает разделители группировки.

new Intl.NumberFormat('en-US', {
  useGrouping: 'always'
}).format(1234);
// "1,234"

Значение "auto" следует предпочтениям локали для группировки. В большинстве локалей принято показывать разделители группировки, поэтому "auto" на практике похоже на "always". Это значение используется по умолчанию, если notation не "compact".

new Intl.NumberFormat('en-US', {
  useGrouping: 'auto'
}).format(1234);
// "1,234"

Значение "min2" показывает разделители групп только если в первой группе как минимум две цифры. Для четырёхзначных чисел это значит, что разделитель не появляется.

new Intl.NumberFormat('en-US', {
  useGrouping: 'min2'
}).format(1234);
// "1234"

new Intl.NumberFormat('en-US', {
  useGrouping: 'min2'
}).format(12345);
// "12,345"

Число 1234 содержит только одну цифру в первой группе (это 1), поэтому разделитель не появляется. Число 12345 содержит две цифры в первой группе (это 12), поэтому разделитель появляется.

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

new Intl.NumberFormat('es-ES', {
  useGrouping: 'auto'
}).format(1234);
// "1234"

new Intl.NumberFormat('es-ES', {
  useGrouping: 'auto'
}).format(12345);
// "12.345"

Значение "auto" учитывает эти локальные предпочтения, а "always" их переопределяет.

new Intl.NumberFormat('es-ES', {
  useGrouping: 'always'
}).format(1234);
// "1.234"

Когда отключать разделители групп

Отключайте разделители групп там, где число — это код, идентификатор или техническое значение, а не количество.

Серийные номера и коды товаров не должны содержать разделителей групп.

const serialNumber = 1234567890;

new Intl.NumberFormat('en-US', {
  useGrouping: false
}).format(serialNumber);
// "1234567890"

Это предотвращает путаницу, является ли разделитель частью значения. Пользователь, увидев 1,234,567,890, может задуматься, важны ли запятые или их нужно вводить при наборе числа в другом месте.

Почтовые индексы, телефонные номера (если они просто числа), и другие идентификаторы с фиксированным форматом лучше показывать без разделителей групп.

const zipCode = 90210;

new Intl.NumberFormat('en-US', {
  useGrouping: false,
  minimumIntegerDigits: 5
}).format(zipCode);
// "90210"

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

console.log(`Processing ${
  new Intl.NumberFormat('en-US', {
    useGrouping: false
  }).format(bytesProcessed)
} bytes`);
// "Processing 1234567 bytes"

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

Когда включать разделители группировки

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

Финансовые суммы проще воспринимать с разделителями группировки.

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: true
}).format(1234567.89);
// "$1,234,567.89"

Разделители помогают пользователям быстро отличать $1,234,567 от $123,456 с первого взгляда.

Статистические данные, аналитические дашборды и отчёты с подсчётами выигрывают от группировки.

const pageViews = 5432198;

new Intl.NumberFormat('en-US', {
  useGrouping: true
}).format(pageViews);
// "5,432,198 views"

Крупные измерения становятся более читаемыми с группировкой.

new Intl.NumberFormat('en-US', {
  style: 'unit',
  unit: 'kilometer',
  useGrouping: true
}).format(384400);
// "384,400 km"

Это расстояние (примерное расстояние до Луны) проще воспринимать как 384,400, чем как 384400.

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

Используйте min2 для аккуратного отображения четырёхзначных чисел

Значение "min2" обеспечивает более аккуратный вид для чисел с четырьмя или пятью знаками. Например, годы обычно выглядят лучше без разделителей.

new Intl.NumberFormat('en-US', {
  useGrouping: 'min2'
}).format(2025);
// "2025"

new Intl.NumberFormat('en-US', {
  useGrouping: 'always'
}).format(2025);
// "2,025"

Большинству читателей привычнее видеть 2025, чем 2,025, когда речь идёт о годе. Настройка "min2" обеспечивает такое поведение автоматически.

Цены в определённых диапазонах тоже выигрывают от такого подхода.

const price = 1299;

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: 'min2'
}).format(price);
// "$1299.00"

Некоторые ритейлеры предпочитают показывать цены вроде $1299 без запятой, чтобы они казались психологически дешевле. Как только цена превышает четыре знака, появляется разделитель.

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: 'min2'
}).format(12999);
// "$12,999.00"

Это даёт вам одинаковое поведение для всего диапазона цен без необходимости вручную проверять разрядность числа.

Как компактная запись влияет на группировку

При использовании компактной записи поведение по умолчанию useGrouping меняется на "min2" вместо "auto". Это предотвращает появление лишних разделителей в компактных форматах.

new Intl.NumberFormat('en-US', {
  notation: 'compact'
}).format(1234);
// "1.2K"

new Intl.NumberFormat('en-US', {
  notation: 'compact',
  useGrouping: 'always'
}).format(1234);
// "1.2K"

Компактная запись уже сокращает число, поэтому внутренние разделители групп будут избыточны. Форматтер учитывает это автоматически, но при необходимости вы можете изменить настройку.

Как узнать, какая настройка группировки активна

Метод resolvedOptions() показывает, какое значение useGrouping реально использует форматтер.

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

formatter.resolvedOptions().useGrouping;
// "auto"

Даже если форматтер был создан без явного указания useGrouping, в итоговых настройках будет показано значение по умолчанию "auto".

const compactFormatter = new Intl.NumberFormat('en-US', {
  notation: 'compact'
});

compactFormatter.resolvedOptions().useGrouping;
// "min2"

Форматтер с компактной записью по умолчанию использует "min2" вместо "auto", как видно в итоговых настройках.

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