Группировка разрядов

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

Примеры:

1000        -> 1,000
1000000     -> 1,000,000
1234567.89  -> 1,234,567.89

В разных локалях правила группировки отличаются:

Локаль Формат
en 1,234,567.89
de 1.234.567,89
fr 1 234 567,89
hi 12,34,567.89

Библиотека Globalize использует данные CLDR и автоматически применяет правила конкретной культуры.


Подключение Globalize

Минимальный набор модулей:

<script src="cldr.js"></script>
<script src="cldr/event.js"></script>
<script src="cldr/supplemental.js"></script>

<script src="globalize.js"></script>
<script src="globalize/number.js"></script>

Загрузка данных локали:

Globalize.load(
    cldrData
);

Globalize.locale("en");

Базовое форматирование чисел

Метод formatNumber() автоматически включает группировку разрядов.

const globalize = new Globalize("en");

globalize.formatNumber(1234567);

Результат:

1,234,567

Для дробных чисел:

globalize.formatNumber(1234567.89);

Результат:

1,234,567.89

Группировка в разных локалях

Английская локаль

const en = new Globalize("en");

en.formatNumber(1234567.89);

Результат:

1,234,567.89

Немецкая локаль

const de = new Globalize("de");

de.formatNumber(1234567.89);

Результат:

1.234.567,89

Особенности:

  • точка используется как разделитель тысяч;
  • запятая — разделитель дробной части.

Французская локаль

const fr = new Globalize("fr");

fr.formatNumber(1234567.89);

Результат:

1 234 567,89

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


Индийская система группировки

Индийский формат отличается от западного.

const hi = new Globalize("hi");

hi.formatNumber(1234567);

Результат:

12,34,567

Принцип:

  • первые три цифры справа образуют группу;
  • далее группировка идет по две цифры.

Управление группировкой через параметры

Метод numberFormatter() позволяет более гибко управлять форматированием.

const formatter = globalize.numberFormatter();

formatter(987654321);

Результат:

987,654,321

Отключение группировки

Параметр useGrouping управляет отображением разделителей.

const formatter = globalize.numberFormatter({
    useGrouping: false
});

formatter(1234567);

Результат:

1234567

Полезно:

  • при экспорте данных;
  • для внутренних вычислений;
  • при генерации идентификаторов;
  • в технических логах.

Принудительное включение группировки

const formatter = globalize.numberFormatter({
    useGrouping: true
});

formatter(1000000);

Результат:

1,000,000

Форматирование денежных значений

Группировка особенно важна при отображении валют.

const formatter = globalize.currencyFormatter("USD");

formatter(1234567.89);

Результат:

$1,234,567.89

Для немецкой локали:

const de = new Globalize("de");

const formatter = de.currencyFormatter("EUR");

formatter(1234567.89);

Результат:

1.234.567,89 €

Форматирование процентов

const formatter = globalize.numberFormatter({
    style: "percent"
});

formatter(0.5678);

Результат:

57%

С группировкой:

formatter(12345.678);

Результат:

1,234,568%

Использование шаблонов форматирования

Globalize поддерживает шаблоны.

Стандартная группировка

const formatter = globalize.numberFormatter({
    raw: "#,##0.###"
});

formatter(1234567.89);

Результат:

1,234,567.89

Фиксированное количество знаков

const formatter = globalize.numberFormatter({
    raw: "#,##0.00"
});

formatter(1234567);

Результат:

1,234,567.00

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

globalize.formatNumber(9876543210123);

Результат:

9,876,543,210,123

Группировка существенно повышает читаемость длинных значений.

Без группировки:

9876543210123

С группировкой:

9,876,543,210,123

Форматирование отрицательных чисел

globalize.formatNumber(-1234567.89);

Результат:

-1,234,567.89

Группировка сохраняется независимо от знака числа.


Форматирование нулевых значений

globalize.formatNumber(0);

Результат:

0
globalize.formatNumber(0.00);

Результат:

0

С шаблоном:

const formatter = globalize.numberFormatter({
    raw: "#,##0.00"
});

formatter(0);

Результат:

0.00

Группировка и округление

const formatter = globalize.numberFormatter({
    maximumFractionDigits: 2
});

formatter(1234567.89123);

Результат:

1,234,567.89

Округление выполняется после применения правил локали.


Минимальное и максимальное количество цифр

Минимум дробных цифр

const formatter = globalize.numberFormatter({
    minimumFractionDigits: 2
});

formatter(1234567);

Результат:

1,234,567.00

Максимум дробных цифр

const formatter = globalize.numberFormatter({
    maximumFractionDigits: 3
});

formatter(1234567.891234);

Результат:

1,234,567.891

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

Создание форматтера — относительно дорогая операция.

Неэффективный вариант:

for (let i = 0; i < numbers.length; i++) {
    const result = globalize.formatNumber(numbers[i]);
}

Более производительный подход:

const formatter = globalize.numberFormatter();

for (let i = 0; i < numbers.length; i++) {
    const result = formatter(numbers[i]);
}

Преимущества:

  • меньше накладных расходов;
  • выше производительность;
  • меньше повторных вычислений.

Форматирование таблиц данных

const formatter = globalize.numberFormatter();

const data = [
    1500,
    250000,
    9876543
];

const formatted = data.map(value => formatter(value));

console.log(formatted);

Результат:

[
    "1,500",
    "250,000",
    "9,876,543"
]

Использование в интерфейсах

Пример отображения чисел в HTML:

const formatter = globalize.numberFormatter();

document.getElementById("price").textContent =
    formatter(1234567.89);

Результат в интерфейсе:

1,234,567.89

Локализация финансовых отчетов

const ru = new Globalize("ru");

const formatter = ru.numberFormatter();

formatter(9876543210);

Результат:

9 876 543 210

Русская локаль использует пробел как разделитель групп.


Отличие Globalize от Intl.NumberFormat

Intl.NumberFormat

new Intl.NumberFormat("en").format(1234567);

Globalize

globalize.formatNumber(1234567);

Преимущества Globalize:

  • использование CLDR;
  • единая инфраструктура локализации;
  • гибкие шаблоны;
  • расширяемость;
  • совместимость со старыми окружениями.

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

Отсутствие данных CLDR

Ошибка:

E_MISSING_CLDR

Причина:

Globalize.load(...)

не был вызван.


Использование неподдерживаемой локали

new Globalize("unknown");

Результат может быть непредсказуемым.


Форматирование строк вместо чисел

Неправильно:

formatter("1000000");

Правильно:

formatter(Number("1000000"));

Практический пример финансовой панели

Globalize.locale("en");

const moneyFormatter =
    Globalize.currencyFormatter("USD");

const numberFormatter =
    Globalize.numberFormatter();

const stats = {
    revenue: 123456789,
    users: 9876543,
    expenses: 45678901
};

console.log(
    moneyFormatter(stats.revenue)
);

console.log(
    numberFormatter(stats.users)
);

console.log(
    moneyFormatter(stats.expenses)
);

Результат:

$123,456,789.00
9,876,543
$45,678,901.00

Комбинирование параметров форматирования

const formatter = globalize.numberFormatter({
    useGrouping: true,
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
});

formatter(1234567.8);

Результат:

1,234,567.80

Форматирование научных данных

const formatter = globalize.numberFormatter({
    maximumFractionDigits: 6
});

formatter(1234567.123456789);

Результат:

1,234,567.123457

Проверка поведения локалей

const locales = ["en", "de", "fr", "ru", "hi"];

locales.forEach(locale => {
    const g = new Globalize(locale);

    console.log(
        locale,
        g.formatNumber(1234567.89)
    );
});

Пример результата:

en 1,234,567.89
de 1.234.567,89
fr 1 234 567,89
ru 1 234 567,89
hi 12,34,567.89

Влияние группировки на UX

Числа без разделителей трудно воспринимаются:

2456789123

После форматирования:

2,456,789,123

Преимущества:

  • быстрее чтение;
  • меньше вероятность ошибки;
  • лучше визуальная структура;
  • удобнее финансовые интерфейсы.

Поддержка пользовательских локалей

Globalize позволяет использовать собственные данные CLDR.

Globalize.load(customCldrData);

Это дает возможность:

  • изменять правила группировки;
  • создавать внутренние корпоративные форматы;
  • адаптировать отображение под региональные стандарты.

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

При обработке больших массивов чисел рекомендуется:

  • переиспользовать форматтеры;
  • избегать постоянного создания экземпляров;
  • заранее загружать CLDR-данные;
  • минимизировать смену локалей во время выполнения.

Пример оптимизированного подхода:

const formatter = globalize.numberFormatter();

const result = numbers.map(formatter);

Сравнение группировки в разных странах

Страна Пример
США 1,234,567.89
Германия 1.234.567,89
Франция 1 234 567,89
Россия 1 234 567,89
Индия 12,34,567.89

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