Как получить список поддерживаемых календарей, валют и часовых поясов
Узнайте, какие значения для интернационализации поддерживает ваша среда JavaScript
Введение
При разработке интернационализированных приложений часто нужно создавать элементы интерфейса, такие как выпадающие списки, селекторы или формы, чтобы пользователи могли выбирать календари, валюты, часовые пояса или другие параметры локализации. Для этого важно знать, какие значения поддерживаются в среде JavaScript.
Вместо того чтобы поддерживать жёстко заданные списки, которые быстро устаревают или содержат значения, не поддерживаемые браузером, JavaScript предоставляет способ узнать поддерживаемые значения во время выполнения. Это гарантирует, что ваше приложение предлагает только те варианты, которые действительно работают в среде пользователя.
Метод Intl.supportedValuesOf() возвращает списки поддерживаемых значений для интернационализации. С помощью этого метода можно получить поддерживаемые календари, валюты, часовые пояса, системы счисления, типы сортировки и единицы измерения, которые доступны в среде JavaScript.
Что возвращает Intl.supportedValuesOf
Метод Intl.supportedValuesOf() принимает одну строку — параметр, который указывает, значения какого типа нужно вернуть. В результате возвращается массив строк с поддерживаемыми значениями этого типа.
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", ...]
Метод поддерживает шесть различных типов ключей:
"calendar"— возвращает поддерживаемые системы календарей"currency"— возвращает поддерживаемые коды валют"timeZone"— возвращает поддерживаемые идентификаторы часовых поясов"numberingSystem"— возвращает поддерживаемые системы счисления"collation"— возвращает поддерживаемые типы сортировки"unit"— возвращает поддерживаемые единицы измерения
Возвращаемый массив всегда отсортирован по алфавиту, не содержит дубликатов и использует канонические идентификаторы по стандарту Unicode.
Если вы передадите неверный ключ, метод выбросит RangeError:
try {
Intl.supportedValuesOf("invalid");
} catch (error) {
console.error(error.name);
// Output: "RangeError"
}
Эта ошибка означает, что вы использовали ключ, который метод не распознаёт.
Получение поддерживаемых календарей
Календарные системы определяют, как рассчитываются и отображаются даты. В разных культурах используются разные календари, и JavaScript поддерживает многие из них через API Intl.
Ключ "calendar" возвращает все календарные системы, поддерживаемые в среде JavaScript:
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", "ethioaa",
// "ethiopic", "gregory", "hebrew", "indian", "islamic",
// "islamic-civil", "islamic-rgsa", "islamic-tbla",
// "islamic-umalqura", "iso8601", "japanese", "persian",
// "roc"]
Самый распространённый календарь — это "gregory", который представляет григорианский календарь, используемый в большинстве стран мира. Другие календари включают:
"buddhist"— тайский буддийский календарь"chinese"— традиционный китайский календарь"islamic"— исламский календарь Хиджры"hebrew"— еврейский календарь"japanese"— японский календарь с названиями эр
Каждый календарь влияет на то, как форматируются и рассчитываются даты. Когда вы используете Intl.DateTimeFormat с определённым календарём, даты отображаются по его правилам:
const date = new Date("2025-10-15");
const gregorianFormat = new Intl.DateTimeFormat("en-US", {
calendar: "gregory",
year: "numeric",
month: "long",
day: "numeric"
});
const islamicFormat = new Intl.DateTimeFormat("en-US", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
console.log(gregorianFormat.format(date));
// Output: "October 15, 2025"
console.log(islamicFormat.format(date));
// Output: "Rabi' II 13, 1447 AH"
Одна и та же дата в JavaScript будет выглядеть по-разному при форматировании с разными календарями.
Использование поддерживаемых календарей для создания селекторов
При создании селектора календаря в интерфейсе получите список поддерживаемых календарей и создайте для каждого из них вариант выбора:
const calendars = Intl.supportedValuesOf("calendar");
const select = document.createElement("select");
calendars.forEach(calendar => {
const option = document.createElement("option");
option.value = calendar;
option.textContent = calendar;
select.appendChild(option);
});
document.body.appendChild(select);
Так создаётся выпадающий список только с теми календарями, которые работают в текущей среде.
Можно улучшить этот селектор, используя Intl.DisplayNames, чтобы показывать человеко-понятные названия календарей:
const calendars = Intl.supportedValuesOf("calendar");
const displayNames = new Intl.DisplayNames(["en-US"], { type: "calendar" });
calendars.forEach(calendar => {
const option = document.createElement("option");
option.value = calendar;
option.textContent = displayNames.of(calendar);
// Creates options like "Gregorian Calendar", "Islamic Calendar", etc.
});
Вместо технических идентификаторов будут отображаться описательные названия.
Получение поддерживаемых валют
Коды валют идентифицируют денежные системы, используемые по всему миру. JavaScript поддерживает сотни валютных кодов на основе стандарта ISO 4217.
Ключ "currency" возвращает все коды валют, поддерживаемые в среде JavaScript:
const currencies = Intl.supportedValuesOf("currency");
console.log(currencies.length);
// Output: typically over 300
console.log(currencies.slice(0, 10));
// Output: ["ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK"]
Коды валют состоят из трёх заглавных букв. Примеры наиболее распространённых:
"USD"— доллар США"EUR"— евро"GBP"— британский фунт стерлингов"JPY"— японская иена"CNY"— китайский юань
В список входят как действующие, так и некоторые исторические валюты, которые уже не используются.
При форматировании денежных значений нужно указывать, какую валюту использовать:
const amount = 1234.56;
const usdFormat = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
});
const eurFormat = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR"
});
console.log(usdFormat.format(amount));
// Output: "$1,234.56"
console.log(eurFormat.format(amount));
// Output: "€1,234.56"
Код валюты определяет, какой символ будет отображаться и как будет форматироваться значение.
Фильтрация валют для выбора пользователем
В большинстве приложений нужно показывать только актуальные и часто используемые валюты. Можно отфильтровать список поддерживаемых валют, чтобы оставить только те, которые важны для ваших пользователей:
const allCurrencies = Intl.supportedValuesOf("currency");
const commonCurrencies = ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"];
const availableCurrencies = commonCurrencies.filter(currency =>
allCurrencies.includes(currency)
);
console.log(availableCurrencies);
// Output: ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"]
Так вы предложите только те валюты, которые соответствуют вашим требованиям и поддерживаются браузером.
Отображение названий валют
При создании селектора валют лучше показывать понятные названия, а не трёхбуквенные коды:
const currencies = ["USD", "EUR", "GBP", "JPY"];
const displayNames = new Intl.DisplayNames(["en-US"], { type: "currency" });
currencies.forEach(currency => {
const name = displayNames.of(currency);
console.log(`${currency}: ${name}`);
});
// Output:
// USD: US Dollar
// EUR: Euro
// GBP: British Pound
// JPY: Japanese Yen
Такой подход улучшает пользовательский опыт, показывая, что означает каждый код.
Получение поддерживаемых часовых поясов
Часовые пояса представляют собой географические регионы, в которых действует одно и то же стандартное время. JavaScript поддерживает сотни идентификаторов часовых поясов на основе базы данных IANA.
Ключ "timeZone" возвращает все идентификаторы часовых поясов, поддерживаемые в среде JavaScript:
const timeZones = Intl.supportedValuesOf("timeZone");
console.log(timeZones.length);
// Output: typically over 400
console.log(timeZones.slice(0, 10));
// Output: ["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa",
// "Africa/Algiers", "Africa/Asmara", "Africa/Bamako",
// "Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre"]
Идентификаторы часовых поясов используют формат Continent/City, например "America/New_York" или "Europe/London". Некоторые идентификаторы содержат дополнительные компоненты, такие как "America/Indiana/Indianapolis".
При форматировании дат и времени часовой пояс определяет, какое локальное время будет отображаться:
const date = new Date("2025-10-15T12:00:00Z");
const newYorkFormat = new Intl.DateTimeFormat("en-US", {
timeZone: "America/New_York",
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
timeZoneName: "short"
});
const tokyoFormat = new Intl.DateTimeFormat("en-US", {
timeZone: "Asia/Tokyo",
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
timeZoneName: "short"
});
console.log(newYorkFormat.format(date));
// Output: "October 15, 2025, 8:00 AM EDT"
console.log(tokyoFormat.format(date));
// Output: "October 15, 2025, 9:00 PM JST"
Один и тот же момент времени отображается как разное локальное время в зависимости от часового пояса.
Создание селекторов часовых поясов
Селекторы часовых поясов должны показывать сотни вариантов так, чтобы пользователи легко ориентировались. Группируйте часовые пояса по регионам, чтобы упростить выбор:
const timeZones = Intl.supportedValuesOf("timeZone");
const grouped = timeZones.reduce((groups, tz) => {
const [region] = tz.split("/");
if (!groups[region]) {
groups[region] = [];
}
groups[region].push(tz);
return groups;
}, {});
console.log(Object.keys(grouped));
// Output: ["Africa", "America", "Antarctica", "Arctic", "Asia",
// "Atlantic", "Australia", "Europe", "Indian", "Pacific", "Etc"]
Такая организация группирует часовые пояса по континентам, чтобы пользователям было проще найти свой регион.
Можно ещё больше упростить выбор, показывая текущий сдвиг для каждого часового пояса:
function getTimeZoneOffset(timeZone) {
const date = new Date();
const formatter = new Intl.DateTimeFormat("en-US", {
timeZone,
timeZoneName: "shortOffset"
});
const parts = formatter.formatToParts(date);
const offsetPart = parts.find(part => part.type === "timeZoneName");
return offsetPart ? offsetPart.value : "";
}
const timeZones = ["America/New_York", "Europe/London", "Asia/Tokyo"];
timeZones.forEach(tz => {
const offset = getTimeZoneOffset(tz);
console.log(`${tz}: ${offset}`);
});
// Output:
// America/New_York: GMT-4
// Europe/London: GMT+1
// Asia/Tokyo: GMT+9
Отображение сдвигов помогает пользователям понять разницу во времени между зонами.
Получение поддерживаемых систем счисления
Системы счисления определяют, как отображаются цифры. Хотя большинство приложений используют стандартные арабские цифры (0-9), во многих языках есть свои традиционные системы счисления.
Ключ "numberingSystem" возвращает все системы счисления, поддерживаемые в среде JavaScript:
const numberingSystems = Intl.supportedValuesOf("numberingSystem");
console.log(numberingSystems.slice(0, 10));
// Output: ["adlm", "ahom", "arab", "arabext", "armn", "armnlow",
// "bali", "beng", "bhks", "brah"]
К распространённым системам счисления относятся:
"latn"— стандартные латинские цифры (0-9)"arab"— арабско-индийские цифры"thai"— тайские цифры"deva"— деванагари, используемые в хинди
Разные системы счисления отображают одно и то же число по-разному:
const number = 12345;
const latinFormat = new Intl.NumberFormat("en-US", {
numberingSystem: "latn"
});
const arabFormat = new Intl.NumberFormat("en-US", {
numberingSystem: "arab"
});
const thaiFormat = new Intl.NumberFormat("en-US", {
numberingSystem: "thai"
});
console.log(latinFormat.format(number));
// Output: "12,345"
console.log(arabFormat.format(number));
// Output: "١٢٬٣٤٥"
console.log(thaiFormat.format(number));
// Output: "๑๒,๓๔๕"
Одно и то же числовое значение выглядит по-разному в зависимости от формы цифр.
Получение поддерживаемых типов сортировки (collation)
Типы сортировки определяют, как строки сравниваются и сортируются. В разных языках свои правила алфавитного порядка.
Ключ "collation" возвращает все типы колляции, поддерживаемые в среде JavaScript:
const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Output: ["big5han", "compat", "dict", "direct", "ducet", "emoji",
// "eor", "gb2312", "phonebk", "phonetic"]
К распространённым типам колляции относятся:
"standard"— для колляции по умолчанию для каждого языка"phonetic"— для фонетической сортировки"pinyin"— для сортировки по пиньиню (китайский)"emoji"— для сортировки эмодзи
Колляция влияет на то, как сортируются массивы строк:
const words = ["ä", "z", "a"];
const standardCollator = new Intl.Collator("de-DE", {
collation: "standard"
});
const phoneticCollator = new Intl.Collator("de-DE", {
collation: "phonetic"
});
console.log(words.sort(standardCollator.compare));
// Output: ["a", "ä", "z"]
console.log(words.sort(phoneticCollator.compare));
// Output: ["a", "ä", "z"]
Разные типы колляции могут давать разный порядок сортировки для одного и того же набора данных.
Получение поддерживаемых единиц
Идентификаторы единиц обозначают такие единицы измерения, как метры, галлоны или градусы Цельсия. JavaScript поддерживает множество типов единиц для форматирования измерений.
Ключ "unit" возвращает все идентификаторы единиц, поддерживаемые в среде JavaScript:
const units = Intl.supportedValuesOf("unit");
console.log(units.slice(0, 10));
// Output: ["acre", "bit", "byte", "celsius", "centimeter", "day",
// "degree", "fahrenheit", "fluid-ounce", "foot"]
К распространённым единицам относятся:
- Длина:
"meter","kilometer","mile","foot" - Вес:
"gram","kilogram","pound","ounce" - Температура:
"celsius","fahrenheit" - Объём:
"liter","gallon" - Цифровые:
"byte","kilobyte","megabyte"
При форматировании измерений указывайте, какую единицу использовать:
const distance = 1000;
const meterFormat = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "meter"
});
const kilometerFormat = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilometer"
});
console.log(meterFormat.format(distance));
// Output: "1,000 m"
console.log(kilometerFormat.format(1));
// Output: "1 km"
Единица определяет, какое сокращение или символ будет отображаться с числом.
Можно комбинировать единицы, используя формат "unit1-per-unit2":
const speed = 100;
const speedFormat = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilometer-per-hour"
});
console.log(speedFormat.format(speed));
// Output: "100 km/h"
Так создаются составные единицы, например, километры в час или мили на галлон.
Создание динамических пользовательских интерфейсов
Основной кейс для Intl.supportedValuesOf() — это создание интерфейсов, которые адаптируются к текущей среде JavaScript. Вместо жёстко заданных опций запрашивайте поддерживаемые значения во время выполнения.
В этом примере создаётся форма настроек, где пользователи могут выбрать предпочитаемый календарь, валюту и часовой пояс:
function buildSettingsForm() {
const form = document.createElement("form");
// Calendar selector
const calendarSelect = buildSelector(
"calendar",
Intl.supportedValuesOf("calendar")
);
form.appendChild(createFormGroup("Calendar", calendarSelect));
// Currency selector
const currencies = ["USD", "EUR", "GBP", "JPY", "CNY"];
const currencySelect = buildSelector("currency", currencies);
form.appendChild(createFormGroup("Currency", currencySelect));
// Time zone selector
const timeZones = Intl.supportedValuesOf("timeZone");
const timeZoneSelect = buildSelector("timeZone", timeZones);
form.appendChild(createFormGroup("Time Zone", timeZoneSelect));
return form;
}
function buildSelector(name, values) {
const select = document.createElement("select");
select.name = name;
values.forEach(value => {
const option = document.createElement("option");
option.value = value;
option.textContent = value;
select.appendChild(option);
});
return select;
}
function createFormGroup(label, input) {
const group = document.createElement("div");
const labelElement = document.createElement("label");
labelElement.textContent = label;
group.appendChild(labelElement);
group.appendChild(input);
return group;
}
document.body.appendChild(buildSettingsForm());
Это создаёт полноценный интерфейс настроек, используя только те значения, которые поддерживаются браузером.
Использование поддерживаемых значений для определения возможностей
Вы можете использовать Intl.supportedValuesOf(), чтобы проверить, поддерживаются ли определённые значения перед их использованием. Это помогает реализовать прогрессивное улучшение и стратегии резервирования.
Проверьте, поддерживается ли конкретный календарь:
function isCalendarSupported(calendar) {
const supported = Intl.supportedValuesOf("calendar");
return supported.includes(calendar);
}
if (isCalendarSupported("islamic")) {
console.log("Islamic calendar is supported");
} else {
console.log("Islamic calendar is not supported");
}
Этот подход работает для любого типа значения:
function isValueSupported(type, value) {
try {
const supported = Intl.supportedValuesOf(type);
return supported.includes(value);
} catch (error) {
return false;
}
}
console.log(isValueSupported("currency", "USD"));
// Output: true
console.log(isValueSupported("timeZone", "America/New_York"));
// Output: true
Блок try-catch обрабатывает ситуации, когда Intl.supportedValuesOf() недоступен в окружении.
Это можно использовать для условной загрузки полифиллов:
async function ensureCalendarSupport(calendar) {
if (!isValueSupported("calendar", calendar)) {
console.log(`Loading polyfill for ${calendar} calendar`);
await import("./calendar-polyfill.js");
}
}
await ensureCalendarSupport("persian");
В этом случае дополнительный код загружается только при необходимости.