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

Intl API: как форматировать даты, числа и валюты по локали

5 min read JavaScript Обновлено 18 Dec 2025
Intl API в JavaScript — форматирование по локали
Intl API в JavaScript — форматирование по локали

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

Что такое Intl API и зачем он нужен

Intl API — это стандартизованный интерфейс в JavaScript для форматирования строк, чисел, дат и валют с учётом локали пользователя. Это позволяет автоматически применить нужный порядок даты, разделители тысяч и десятичные разделители, локальные названия валют и единиц.

Кратко:

  • Intl.DateTimeFormat — форматирование дат и времени.
  • Intl.NumberFormat — форматирование чисел, процентов, валют и единиц.

Важно: Intl опирается на реализацию движка (ICU) в браузере и операционной системе, поэтому вывод может немного отличаться между средами.

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

Лучший практический способ — проверить navigator.languages и navigator.language. navigator.languages возвращает массив предпочтений пользователя, отсортированный по приоритету.

Код для получения локали:

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

console.log(getUserLocale());

Пояснение: возвращается BCP 47 тэг, например “en-US” или “ru-RU”. Используйте его в конструкторе Intl.

Форматирование дат: Intl.DateTimeFormat

Intl.DateTimeFormat принимает локаль и объект опций, где можно задать формат для weekday, year, month, day и других компонент.

Простой пример:

const date = Date.now();
const locale = getUserLocale();

const options = {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric",
};

const formatter = new Intl.DateTimeFormat(locale, options);
console.log(formatter.format(date)); // пример: "пятница, 24 марта 2023 г."

Советы:

  • Для компактного формата используйте { year: “2-digit”, month: “short”, day: “2-digit” }.
  • Для времени добавьте hour, minute, second и параметр hour12 для 12/24-часового формата.
  • Для временных зон используйте timeZone: “Europe/Moscow” или Intl API по умолчанию возьмёт системную зону.

Ограничения:

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

Форматирование чисел: Intl.NumberFormat

Intl.NumberFormat форматирует десятичные числа, проценты, валюты и единицы. Вы задаёте локаль и options.

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

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

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" в en-US

Проценты:

const num = 0.1234; // 12.34%
const locale = getUserLocale();

const options = { style: "percent", maximumFractionDigits: 2 };
const pct = new Intl.NumberFormat(locale, options);
console.log(pct.format(num)); // "12.34%" (в зависимости от локали)

Примечание: передавать 123456 как процент даёт 12 345 600% — обычно проценты задают как дробь от 1.

Валюты

Для валют укажите style: “currency” и currency: “USD”/“EUR” и т.д. currencyDisplay контролирует отображение (symbol, code, name).

const num = 123456;
const locale = getUserLocale(); // "ru-RU" или "en-US"

const options = {
  style: "currency",
  currency: "USD",
  currencyDisplay: "code", // "USD 123,456.00" или локальная форма
};

const money = new Intl.NumberFormat(locale, options);
console.log(money.format(num));

Советы по валютам:

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

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

Intl.NumberFormat поддерживает style: “unit” и unit: “liter”/“meter”/“kilogram” и т.д. unitDisplay: “long”|”short”|”narrow”.

const num = 123456;
const locale = getUserLocale();

const options = { style: "unit", unit: "liter", unitDisplay: "long" };
const fmt = new Intl.NumberFormat(locale, options);
console.log(fmt.format(num)); // "123 456 liters" или локальная форма

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

Когда Intl может не подойти (контрпримеры)

  • Если вам нужны одинаковые вывода на всех платформах (byte-for-byte) — Intl даст разные строки в разных реализациях. В этом случае лучше использовать библиотеку с собственным шаблоном вывода.
  • Если целевая среда — очень старые браузеры без Intl (IE < 11) — потребуется полифилл или сторонняя библиотека.
  • Если вы должны переводить и управлять форматами извне (например, CMS) — возможно, удобнее хранить форматные строки на сервере.

Альтернативы и полифиллы

  • Luxon — современная библиотека для дат (использует Intl когда доступен).
  • Day.js — лёгкая замена Moment.js, плагинная архитектура.
  • date-fns — набор утилит для дат, не всегда локализует вывод автоматически.
  • Polyfill: “Intl.js” или пакет “@formatjs/intl” для старых окружений.

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

Руководство по внедрению (мини-методология)

  1. Определите требуемые локали и бизнес-правила (валюта пользователя, формат даты в UI, округление).
  2. Используйте navigator.languages[0] с фоллбеком на navigator.language.
  3. Централизуйте форматтеры в утилитный модуль (например, utils/formatters.js) и переиспользуйте их.
  4. Покройте юнит-тестами критичные форматы (набор примеров вход/ожидаемый вывод для ключевых локалей).
  5. Для старых браузеров добавьте полифилл и протестируйте в CI с эмуляцией окружений.
  6. Документируйте правила отображения для локализаторов.

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

Таблица совместимости (общая):

  • Современные версии Chrome, Firefox, Safari и Edge имеют хорошую поддержку Intl.
  • Node.js поддерживает Intl, но поведение зависит от сборки и ICU.
  • Для старых браузеров (IE11 и ниже) потребуется полифилл.

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

  • Вынесите вызовы Intl в один слой — это упростит подмену реализации.
  • Добавьте feature-detection: if (typeof Intl === “undefined”) { / подгрузить полифилл / }.

Проверки и тесты (кейсы приёмки)

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

  • Для каждой критичной локали проверяется формат даты, времени, валюты и процента.
  • Для валюты: корректная валюта и отображение символа/кода.
  • Для процентов: входные значения интерпретируются как доля (0.5 => 50%).

Примеры тест-кейсов:

  • Формат даты для “en-US” и “ru-RU” для одной и той же отметки времени.
  • Формат валюты USD для пользователей в разных локалях.
  • Отладка: если locales содержит несуществующий тэг — Intl должен фоллбекнуть на «en» или системную локаль.

Чеклист ролей

Для разработчика:

  • Централизуйте форматтеры.
  • Добавьте unit-тесты для ключевых локалей.
  • Обеспечьте фоллбеки и полифиллы.

Для продукт-менеджера:

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

Для локализатора:

  • Проверьте вывод дат и единиц в целевом языке.
  • Подготовьте примеры с реальными значениями для проверки.

Decision tree: Intl или библиотека

flowchart TD
  A[Нужна локализация форматов?] -->|Да| B{Целевые окружения}
  B -->|Современные браузеры + Node| C[Использовать Intl]
  B -->|Старые браузеры/IE| D[Intl + полифилл или библиотека]
  B -->|Единый вывод на всех платформах| E[Использовать библиотеку с собственным шаблоном]
  A -->|Нет| F[Обычный стринг-форматинг]

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

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

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

  • Локаль возвращает “und” или пустую строку — используйте дефолт “en” или ваш продуктовый дефолт.
  • Пользователь выбрал язык, не поддерживаемый ваш интерфейс — предоставьте загрузку локализованных ресурсов и fallback-тексты.

Краткий глоссарий

  • BCP 47: стандарт для меток локалей (например, “en-US”).
  • ICU: библиотека для интернационализации, на которой основан Intl.
  • Фоллбек: резервный вариант, если нужная локаль не поддерживается.

Итог и рекомендации

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

Короткий чек-план внедрения:

  1. Добавьте getUserLocale().
  2. Вынесите formatter-обёртки.
  3. Напишите тесты для ключевых локалей.
  4. Добавьте полифилл для старых окружений.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

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

Что автоматизировать в умном доме
Умный дом

Что автоматизировать в умном доме

Philips Hue Bridge — настройка и возможности
Умный дом

Philips Hue Bridge — настройка и возможности

Adobe Camera Raw: полное руководство по RAW
Фотография

Adobe Camera Raw: полное руководство по RAW

Google Street View: как открыть на телефоне и ПК
Навигация

Google Street View: как открыть на телефоне и ПК

Amazon Music Prime — как начать слушать
Музыка

Amazon Music Prime — как начать слушать

Индексация файлов в Windows 11 — руководство
Windows

Индексация файлов в Windows 11 — руководство