Как проверить, какую локаль и параметры фактически использует форматтер?
Используйте метод resolvedOptions(), чтобы изучить фактическую конфигурацию любого форматтера Intl
Введение
Когда вы создаёте форматировщик Intl в JavaScript, запрашиваемые вами параметры не всегда совпадают с теми, которые вы получаете. Браузер выполняет согласование локали, заполняет значения по умолчанию и нормализует ваши настройки для создания окончательной конфигурации. Метод resolvedOptions() позволяет вам точно узнать, какие параметры фактически использует форматировщик.
Каждый форматировщик в API Intl имеет метод resolvedOptions(). Это включает в себя Intl.DateTimeFormat, Intl.NumberFormat, Intl.ListFormat, Intl.PluralRules, Intl.Collator и другие. Метод возвращает объект, содержащий все детали конфигурации, которые форматировщик использует после обработки вашего ввода.
Этот метод в основном полезен для отладки, понимания поведения браузера и определения доступных функций в текущей среде.
Основной синтаксис
Метод resolvedOptions() не принимает параметров. Вы вызываете его для любого экземпляра форматировщика, и он возвращает объект.
const formatter = new Intl.DateTimeFormat('en-US');
const options = formatter.resolvedOptions();
console.log(options);
// {
// locale: 'en-US',
// calendar: 'gregory',
// numberingSystem: 'latn',
// timeZone: 'America/Los_Angeles',
// ...
// }
Возвращаемый объект всегда включает как минимум свойства locale, calendar и numberingSystem для форматировщиков дат или locale и numberingSystem для форматировщиков чисел. Дополнительные свойства зависят от указанных вами параметров и поддерживаемых возможностей типа форматировщика.
Почему запрашиваемые параметры отличаются от разрешённых
Существует три основные причины, по которым запрашиваемые вами параметры могут отличаться от разрешённых.
Во-первых, согласование локали находит наиболее подходящую доступную локаль, если ваш точный запрос не поддерживается. Если вы запрашиваете de-AT, но в браузере есть только de, разрешённая локаль будет de.
const formatter = new Intl.DateTimeFormat('de-AT-u-ca-buddhist');
const options = formatter.resolvedOptions();
console.log(options.locale);
// Вероятно, вывод: 'de-AT' или 'de'
console.log(options.calendar);
// Вероятно, вывод: 'gregory' (если буддийский календарь не поддерживается)
Во-вторых, браузер заполняет значения по умолчанию для любых параметров, которые вы не указываете. Эти значения по умолчанию зависят от локали.
const formatter = new Intl.NumberFormat('en-US');
const options = formatter.resolvedOptions();
console.log(options.style);
// Вывод: 'decimal'
console.log(options.minimumFractionDigits);
// Вывод: 0
console.log(options.maximumFractionDigits);
// Вывод: 3
В-третьих, браузер нормализует определённые параметры в их каноническую форму. Если вы используете dateStyle или timeStyle, браузер не включает их в разрешённые параметры. Вместо этого он включает отдельные параметры компонентов, на которые они разворачиваются.
Проверка фактически используемой локали
locale в свойствах resolved options точно указывает, какую локаль использует форматтер. Это результат согласования локалей.
const formatter = new Intl.DateTimeFormat(['zh-TW', 'zh-CN', 'en-US']);
const options = formatter.resolvedOptions();
console.log(options.locale);
// Выводит первую поддерживаемую локаль из списка
Если вы запрашиваете локаль с ключевыми словами расширения Unicode, результирующая локаль может не включать эти ключевые слова, если они не поддерживаются или были применены как отдельные параметры.
const formatter = new Intl.NumberFormat('en-US-u-nu-arab');
const options = formatter.resolvedOptions();
console.log(options.locale);
// Может вывести: 'en-US'
console.log(options.numberingSystem);
// Может вывести: 'arab' или 'latn' в зависимости от поддержки
Изучение параметров форматирования даты и времени
Для Intl.DateTimeFormat resolved options включают детали о том, какие компоненты даты и времени будут отображаться и как.
const formatter = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/New_York'
});
const options = formatter.resolvedOptions();
console.log(options.year);
// Выводит: 'numeric'
console.log(options.month);
// Выводит: 'long'
console.log(options.day);
// Выводит: 'numeric'
console.log(options.timeZone);
// Выводит: 'America/New_York'
console.log(options.calendar);
// Выводит: 'gregory'
Когда вы используете dateStyle или timeStyle, эти сокращения не включаются в resolved options. Браузер разворачивает их в отдельные параметры компонентов на основе локали.
const formatter = new Intl.DateTimeFormat('en-US', {
dateStyle: 'full'
});
const options = formatter.resolvedOptions();
console.log(options.dateStyle);
// Выводит: undefined
console.log(options.weekday);
// Выводит: 'long'
console.log(options.year);
// Выводит: 'numeric'
console.log(options.month);
// Выводит: 'long'
console.log(options.day);
// Выводит: 'numeric'
Если вы создаете форматтер даты без каких-либо параметров, resolved options покажут, какие параметры по умолчанию выбрал браузер для этой локали.
const formatter = new Intl.DateTimeFormat('ja-JP');
const options = formatter.resolvedOptions();
console.log(options);
// Показывает параметры компонентов даты по умолчанию для японской локали
Изучение параметров форматирования чисел
Для Intl.NumberFormat метод resolvedOptions предоставляет информацию о стиле, точности, группировке и других деталях форматирования.
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
const options = formatter.resolvedOptions();
console.log(options.style);
// Вывод: 'currency'
console.log(options.currency);
// Вывод: 'USD'
console.log(options.currencyDisplay);
// Вывод: 'symbol'
console.log(options.minimumFractionDigits);
// Вывод: 2
console.log(options.maximumFractionDigits);
// Вывод: 2
Вы можете заметить, что, даже указав только валюту, браузер заполнил значения по умолчанию для currencyDisplay и дробных разрядов.
Когда вы используете параметры округления, метод resolvedOptions показывает, как именно будут округляться числа.
const formatter = new Intl.NumberFormat('en-US', {
minimumSignificantDigits: 3,
maximumSignificantDigits: 5
});
const options = formatter.resolvedOptions();
console.log(options.minimumSignificantDigits);
// Вывод: 3
console.log(options.maximumSignificantDigits);
// Вывод: 5
Изучение других типов форматировщиков
Метод resolvedOptions() работает одинаково для всех форматировщиков Intl.
Для Intl.ListFormat он показывает тип и стиль.
const formatter = new Intl.ListFormat('en-US', {
style: 'long',
type: 'conjunction'
});
const options = formatter.resolvedOptions();
console.log(options.locale);
// Вывод: 'en-US'
console.log(options.style);
// Вывод: 'long'
console.log(options.type);
// Вывод: 'conjunction'
Для Intl.PluralRules он показывает тип и минимальное/максимальное количество разрядов.
const formatter = new Intl.PluralRules('en-US', {
type: 'ordinal'
});
const options = formatter.resolvedOptions();
console.log(options.locale);
// Вывод: 'en-US'
console.log(options.type);
// Вывод: 'ordinal'
console.log(options.minimumIntegerDigits);
// Вывод: 1
Общие случаи использования resolvedOptions()
Наиболее распространенный случай использования — отладка. Когда отформатированный вывод не соответствует вашим ожиданиям, resolvedOptions() помогает понять, что именно делает форматировщик.
const formatter = new Intl.DateTimeFormat('en-US', {
dateStyle: 'medium'
});
console.log(formatter.format(new Date()));
// Проверьте вывод
console.log(formatter.resolvedOptions());
// Узнайте, какие параметры привели к этому выводу
Другой случай использования — обнаружение возможностей. Вы можете проверить, поддерживается ли определенный календарь, система нумерации или другая функция, запросив её и посмотрев, что было фактически разрешено.
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic'
});
const options = formatter.resolvedOptions();
if (options.calendar === 'islamic') {
console.log('Исламский календарь поддерживается');
} else {
console.log('Исламский календарь не поддерживается, используется ' + options.calendar);
}
Вы также можете использовать resolvedOptions() для получения предпочтений локали пользователя. Когда вы создаете форматировщик без аргумента локали, браузер использует предпочтения пользователя.
const formatter = new Intl.DateTimeFormat();
const options = formatter.resolvedOptions();
console.log(options.locale);
// Вывод: предпочтительная локаль пользователя
console.log(options.timeZone);
// Вывод: часовой пояс пользователя
console.log(options.hourCycle);
// Вывод: предпочтение пользователя по формату времени (12 или 24 часа)
Наконец, вы можете использовать разрешенные параметры для создания идентичного форматировщика. Возвращенный объект можно передать обратно в конструктор.
const formatter1 = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
const options = formatter1.resolvedOptions();
const formatter2 = new Intl.NumberFormat(options.locale, options);
// formatter2 будет форматировать числа так же, как formatter1
Основные выводы
Метод resolvedOptions() возвращает объект, содержащий фактическую конфигурацию, которую использует форматтер. Эта конфигурация может отличаться от запрошенной вами из-за согласования локали, значений по умолчанию и нормализации.
Каждый форматтер Intl имеет этот метод. Вы вызываете его без параметров и получаете объект со свойствами, такими как locale, calendar, numberingSystem и специфические для форматтера опции.
Используйте resolvedOptions() в основном для отладки поведения форматтера, обнаружения доступных функций и понимания того, как браузер интерпретировал ваши параметры. Возвращаемый объект также можно использовать для создания идентичного форматтера или анализа предпочтений пользователя.