Гид по технологиям

Intl API для форматирования дат, чисел, валют и единиц в JavaScript

7 min read Localization Обновлено 03 Jan 2026
Intl API: форматирование дат, чисел и валют
Intl API: форматирование дат, чисел и валют

Большой логотип JavaScript на синем фоне

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

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

Получение локали пользователя

Конструкторы Intl принимают локаль и объект опций. По локали они выбирают способ форматирования.

Для получения локали на клиенте обычно используют navigator.language и navigator.languages. navigator.language возвращает одиночный BCP 47 тег (например, “en-US”), а navigator.languages — массив предпочтительных локалей, отсортированный по приоритету.

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

const getUserLocale = () => {  
  if (navigator.languages && navigator.languages.length) {  
    return navigator.languages[0];  
  }  
  return navigator.language;  
};  
  
console.log(getUserLocale());  

Важно: при серверном рендеринге или в средах без объекта navigator локаль обычно нужно получать из заголовков запроса (Accept-Language) или из пользовательских настроек в профиле.

Форматирование дат

Intl.DateTimeFormat принимает локаль и набор опций. Помимо weekday, year, month и day есть расширенные опции для времени и временной зоны.

Ключевые опции:

  • weekday: long, short, narrow
  • year: numeric, 2-digit
  • month: numeric, 2-digit, long, short, narrow
  • day: numeric, 2-digit
  • hour, minute, second: numeric, 2-digit
  • timeZone: строка IANA, например “UTC” или “Europe/Moscow”
  • timeZoneName: short, long
  • hour12: true/false
  • dateStyle / timeStyle: full, long, medium, short (удобно для быстрых настроек)

Пример форматирования даты с опциями:

const date = Date.now()  
const locale = getUserLocale();  
  
const options = {  
  weekday: "long",  
  year: "numeric",  
  month: "long",  
  day: "numeric",  
};  
  
const formatter = new Intl.DateTimeFormat(locale, options);  
  
// weekday, month date, year (Friday, March 24, 2023)  
console.log(formatter.format(date));

Дополнительные приёмы и полезные методы:

  • formatToParts(date) возвращает массив частей (weekday, day, literal и т. д.), что удобно для составления пользовательских шаблонов.
  • resolvedOptions() показывает фактические параметры форматтера после сопоставления с поддерживаемыми локалями.

Пример с временной зоной и форматированием времени:

const date = new Date();
const formatter = new Intl.DateTimeFormat('ru-RU', {
  dateStyle: 'long',
  timeStyle: 'short',
  timeZone: 'Europe/Moscow'
});
console.log(formatter.format(date));

Заметка: поведение dateStyle/timeStyle и поддержка форматных комбинаций могут отличаться между браузерами и версиями ICU, поэтому тесты по целевым локалям обязательны.

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

Intl.NumberFormat форматирует числа с учётом локали и опций. Опции зависят от выбранного style.

Основные опции:

  • style: decimal, percent, currency, unit
  • minimumFractionDigits, maximumFractionDigits
  • useGrouping: true/false — разделители тысяч
  • notation: standard, scientific, engineering, compact
  • compactDisplay: short, long
  • signDisplay: auto, always, never, exceptZero

Десятичные числа и проценты

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

const num = 123456;  
const locale = getUserLocale();  // en-US  
  
const options = {  
  style: "decimal",  
  minimumFractionDigits: 2,  
  maximumFractionDigits: 2,  
  useGrouping: true,  
};  
  
const formatter = new Intl.NumberFormat(locale, options);  
  
console.log(formatter.format(num));  // 123,456.00  

Проценты:

const num = 123456;  
const locale = getUserLocale();  
  
const options = {  
  style: "percent",  
  useGrouping: true,  
};  
  
const formatter = new Intl.NumberFormat(locale, options);  
  
console.log(formatter.format(num));  // 12,345,600%  

Примечание: стиль percent умножает число на 100 и добавляет знак процента; будьте внимательны к входным данным.

Валюты

Для форматирования валют используйте style: “currency” и укажите currency (ISO 4217): “USD”, “EUR”, “RUB” и т. п. Рекомендуется всегда явно указывать currency — в разных средах отсутствие этого параметра может привести к ошибке или непредсказуемому результату.

Опция currencyDisplay управляет тем, как будет показана валюта: symbol, code или name.

Пример:

const num = 123456;  
const locale = getUserLocale();  // en-US  
  
const options = {  
  style: "currency",  
  currency: "USD",  
  currencyDisplay: "code",  
};  
  
const formatter = new Intl.NumberFormat(locale, options);  
  
console.log(formatter.format(num));  // USD 123,456.00  

Если нужно показать валюту в локальном формате с символом и двумя знаками после запятой, используйте currencyDisplay: “symbol” и minimumFractionDigits/maximumFractionDigits при необходимости.

Единицы измерения

Для форматирования единиц установите style: “unit” и укажите unit (например, “meter”, “kilogram”, “liter”, “second”). unitDisplay задаёт вид отображения: long, short, narrow.

Пример:

const num = 123456;  
const locale = getUserLocale();  
  
const options = {  
  style: "unit",  
  unit: "liter",  
  unitDisplay: "long",  
};  
  
const formatter = new Intl.NumberFormat(locale, options);  
  
console.log(formatter.format(num)); //123,456 liters  

Замечание: список поддерживаемых единиц и их имен зависит от реализации ICU в среде выполнения.

Полезные приёмы и шаблоны

  • Выносите логику форматирования в отдельный слой (утилиты или сервис локализации). Это упрощает тестирование и замену реализации.
  • Используйте formatToParts, если нужно встроить отформатированные числа/даты в сложные DOM-шаблоны с разной разметкой для цифр и символов.
  • Для отображения дат/чисел в приложении выбирайте локаль по профилю пользователя, затем по Accept-Language, затем по настройкам браузера — в этом порядке.
  • Для финансовых операций всегда храните суммы в минимальных единицах (копейки/центы) или в числовом типе с фиксированной точностью и форматируйте для показа.

Когда Intl не подходит

Важно понимать сценарии, где Intl может оказаться недостаточным:

  • старые браузеры или минимальные сборки ICU в Node.js, где некоторые локали или опции не поддерживаются;
  • требования к единообразному отображению между клиентом и сервером при SSR, если сервер использует другую версию ICU;
  • специфические правила локализации, которых нет в стандартной базе (напр., нетипичные формы склонения валютных названий или кастомные шаблоны дат);
  • корпоративные форматы для отчётов, которые не укладываются в стандартные опции.

В таких случаях рассмотрите полифилл Intl (например, intl-pluralrules/polyfill или полный ICU для Node.js) либо сторонние библиотеки (Luxon, date-fns, Day.js) с явной локализацией и более предсказуемой поддержкой.

Совместимость и миграция

  • Node.js: Intl использует ICU. В некоторых сборках Node может быть включён урезанный набор локалей (small-icu). Для полного набора локалей требуется сборка с full-icu или установка соответствующих пакетов.
  • Браузеры: современные версии Chrome, Firefox, Safari, Edge предоставляют широкую поддержку Intl, но детали (например, dateStyle/timeStyle, набор единиц) могут отличаться.
  • SSR: при рендеринге на сервере убедитесь, что серверная среда поддерживает те же локали и правила форматирования, что и клиент.

Миграционные советы:

  • Покройте тестами основные целевые локали.
  • Включите проверку resolvedOptions() в тестах, чтобы убедиться, что форматтер использует ожидаемые параметры.
  • При добавлении полифилла проверяйте размер бандла и impact на производительность.

Роль‑ориентированные чеклисты

Разработчик:

  • Вынести форматтеры в утилиты.
  • Всегда передавать локаль явно при вызове (если есть основной контекст локали).
  • Использовать formatToParts при необходимости стилизовать части.

Дизайнер/UX:

  • Убедиться, что макеты выдерживают разные длины строк для локалей (напр., немецкие слова длиннее).
  • Проверить расположение символов валют и порядок элементов даты.

Тестировщик/Локализатор:

  • Написать тесты для каждой целевой локали с контрольными примерами.
  • Проверить поведение при нестандартных локалях (например, zh-Hant, ru-RU, ar-EG).

Критерии приёмки

  • Дата отображается в формате, соответствующем выбранной локали и опциям.
  • Числа отображаются с правильными разделителями и количеством знаков.
  • Валюты показываются с ожидаемым символом/кодом/названием.
  • Форматирование остаётся стабильным при смене локали и при SSR.

Тест‑кейсы и примеры проверки

  1. Проверка простого форматирования даты для ru-RU, en-US, ja-JP.
  2. Проверка форматирования валюты USD, EUR, RUB и поведение при отсутствии currency.
  3. Форматирование процентов: 0.123 => 12.3% (в зависимости от minimumFractionDigits).
  4. Отображение единиц: liter, meter, kilogram в нескольких локалях.
  5. formatToParts: собирать число и проверять, что части (integer, group, decimal, fraction, literal) соответствуют ожидаемым для локали.

Примеры кода: расширенные

Форматирование с notation и compact:

const numbers = [1000, 12_345_678];
const compactFormatter = new Intl.NumberFormat('en-US', { notation: 'compact', compactDisplay: 'short' });
console.log(numbers.map(n => compactFormatter.format(n))); // ['1K', '12M'] (зависит от локали)

const sciFormatter = new Intl.NumberFormat('en-US', { notation: 'scientific', maximumFractionDigits: 2 });
console.log(sciFormatter.format(12345)); // '1.23E4'

Использование formatToParts для встраивания в DOM:

const formatter = new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB' });
const parts = formatter.formatToParts(123456.78);
// parts — массив объектов {type: 'integer'|'group'|'decimal'|'fraction'|'currency'|'literal', value: '...'}
// можно сгенерировать элементы  для каждой части с отдельным классом

Ментальные модели и эвристики

  • «Локаль определяет форму, опции — детализацию». Локаль задаёт порядок и символы, опции — сколько знаков и какой стиль.
  • «Форматирование для показа != хранение»: храните данные в нейтральном формате, форматируйте только при отображении.
  • «Fallback — явное, а не магический выбор»: лучше явно указывать currency и ключевые опции, чем полагаться на поведение реализации.

Мини‑методология внедрения Intl в проект

  1. Определить список целевых локалей и приоритеты.
  2. Вынести утилиты форматирования и централизовать доступ к текущей локали.
  3. Покрыть примерными тестами ключевые форматы (дата, валюта, процент, единицы).
  4. Провести smoke‑тесты в целевых браузерах и на сервере.
  5. При необходимости добавить полифилл или стороннюю библиотеку.

Безопасность и приватность

Intl не отправляет пользовательских данных наружу — это локальная библиотека. Однако при выборе локали из заголовков (Accept-Language) или профиля учитывайте потенциальные побочные каналы (фингерпринтинг): излишне детальные данные о локали могут дополняться сессиями аналитики.

Важно: храните пользовательские настройки локали в профиле только если это ожидаемое поведение, и давайте пользователю возможность изменить отображение.

Краткий словарь

  • Локаль: BCP 47 тег, например ru-RU, en-US.
  • ICU: библиотека для интернационализации, которую используют среды выполнения.
  • formatToParts: метод для получения частей отформатированной строки.
  • currencyDisplay: опция для управления показом валюты.

Альтернативы

  • Luxon: современная библиотека для работы с датами/временем с хорошей поддержкой временных зон.
  • Day.js и date-fns: компактные библиотеки для манипуляций с датами; локализация реализуется отдельными пакетами.
  • Полифиллы Intl: для старых браузеров или когда нужно единообразие ICU.

Итог

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

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

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Отключение PCA в Windows
Windows

Отключение PCA в Windows

Проблемы при обновлении до Windows 7 — решения
Windows

Проблемы при обновлении до Windows 7 — решения

Переустановка Windows 7 без потери настроек
Windows

Переустановка Windows 7 без потери настроек

Windows 10 приложение для Arduino — пошагово
Разработка

Windows 10 приложение для Arduino — пошагово

4×4×4 LED‑куб на Arduino — полное руководство
Электроника

4×4×4 LED‑куб на Arduino — полное руководство

Санта в Alexa: как включить и что спросить
Умный дом

Санта в Alexa: как включить и что спросить