ECMAScript Internationalization API (Intl) представляет собой встроенный в JavaScript набор инструментов для локализации и культурно-зависимой обработки данных: чисел, дат, строк, списков и языковых форм. API стандартизирован спецификацией ECMA-402 и интегрирован в современные JavaScript-движки, обеспечивая единый подход к международной адаптации приложений без внешних библиотек.
Основная идея заключается в разделении данных и их представления: логика приложения оперирует абстрактными значениями, а слой Intl отвечает за форматирование с учётом локали пользователя, правил языка и региональных особенностей.
Ключевым понятием является локаль — строковый идентификатор языка и региона, соответствующий стандарту BCP 47.
Примеры:
en — английский языкen-US — английский (США)ru-RU — русский (Россия)zh-Hans-CN — китайский (упрощённая письменность,
Китай)Локаль может включать:
Разрешение локали происходит через механизм locale resolution, где движок сопоставляет запрошенную локаль с поддерживаемыми вариантами.
Глобальный объект Intl служит контейнером для всех
форматтеров и утилит:
Intl.NumberFormatIntl.DateTimeFormatIntl.CollatorIntl.PluralRulesIntl.RelativeTimeFormatIntl.ListFormatIntl.DisplayNamesIntl.SegmenterКаждый из этих конструкторов создаёт специализированный форматтер, который инкапсулирует правила конкретной локали.
Общая архитектура основана на двух шагах:
format,
formatToParts, resolvedOptions)Используется для локализованного представления чисел, валют и процентов.
const nf = new Intl.NumberFormat('ru-RU');
nf.format(1234567.89); // "1 234 567,89"
Валюта:
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(1234.5); // "$1,234.50"
Проценты:
new Intl.NumberFormat('en-US', {
style: 'percent'
}).format(0.25); // "25%"
Единицы измерения:
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer-per-hour'
}).format(100);
Опции управления:
minimumFractionDigitsmaximumFractionDigitsuseGroupingМетод formatToParts() возвращает структуру токенов,
полезную для кастомного UI.
Форматирование дат зависит от культурных правил: порядок компонентов, разделители, названия месяцев.
const dtf = new Intl.DateTimeFormat('ru-RU');
dtf.format(new Date());
new Intl.DateTimeFormat('en-GB', {
dateStyle: 'full',
timeStyle: 'long'
});
yearmonthdayhourminutesecondweekdaynew Intl.DateTimeFormat('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
});
new Intl.DateTimeFormat('en-US', {
timeZone: 'UTC'
});
Поддержка IANA time zone database обеспечивает корректное отображение времени независимо от локальной системы.
Используется для выражений вида «3 дня назад» или «через 2 часа».
const rtf = new Intl.RelativeTimeFormat('ru-RU');
rtf.format(-1, 'day'); // "1 день назад"
rtf.format(2, 'hour'); // "через 2 часа"
Поддерживаемые единицы:
Опция numeric позволяет управлять формой:
new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
Языки различают формы слов в зависимости от числа.
const pr = new Intl.PluralRules('ru-RU');
pr.select(1); // "one"
pr.select(2); // "few"
pr.select(5); // "many"
Используется для построения локализованных сообщений:
const forms = {
one: 'яблоко',
few: 'яблока',
many: 'яблок'
};
Предназначен для корректной сортировки строк с учётом языка.
const collator = new Intl.Collator('ru-RU');
['яблоко', 'арбуз', 'груша'].sort(collator.compare);
sensitivity (base, accent, case, variant)numeric (учёт чисел в строках)ignorePunctuationnew Intl.Collator('en', { numeric: true }).compare('file2', 'file10');
Используется для корректного соединения элементов списка.
const lf = new Intl.ListFormat('ru-RU');
lf.format(['яблоки', 'груши', 'сливы']);
// "яблоки, груши и сливы"
Типы:
conjunction (и)disjunction (или)unit (единицы измерения)Позволяет получать локализованные названия языков, регионов и валют.
const dn = new Intl.DisplayNames('ru-RU', { type: 'language' });
dn.of('en'); // "английский"
dn.of('fr'); // "французский"
Типы:
Используется для разбиения текста на границы: слова, предложения, графемы.
const segmenter = new Intl.Segmenter('en', { granularity: 'word' });
[...segmenter.segment('Hello world')].map(s => s.segment);
Гранулярность:
Особенно важно для языков без пробелов (например, китайский, японский).
При создании любого форматтера происходит:
en-US →
en)new Intl.NumberFormat(['fr-CA', 'fr', 'en']);
Метод:
resolvedOptions()
возвращает фактически выбранные параметры:
nf.resolvedOptions();
Создание экземпляров Intl является относительно дорогой операцией. Оптимизация строится на:
const formatter = new Intl.NumberFormat('ru-RU');
function format(value) {
return formatter.format(value);
}
Intl реализован в:
Полнота функциональности зависит от версии ICU, встроенной в движок.
Общие механизмы, встречающиеся в разных конструкторах:
localeMatcher: алгоритм выбора локали
(best fit или lookup)style: формат представленияnotation: научная или инженерная нотация
(NumberFormat)signDisplay: управление знаком числаМногие форматтеры поддерживают метод:
formatToParts()
Пример:
new Intl.NumberFormat('ru-RU').formatToParts(1234);
Результат представляет массив объектов:
{ type: 'integer', value: '1' }{ type: 'group', value: ' ' }Это позволяет строить кастомные интерфейсы, где каждая часть числа или даты стилизуется отдельно.
Intl опирается на стандарты Unicode:
Это обеспечивает согласованность поведения между платформами и языками.
Особое внимание уделяется:
Intl часто используется как базовый слой в:
Архитектурно он выступает как низкоуровневый форматтер, поверх которого строятся i18n-библиотеки более высокого уровня.