Как получить список поддерживаемых календарей, валют, часовых поясов

Узнайте, какие значения интернационализации поддерживает ваша среда JavaScript

Введение

При создании интернационализированных приложений часто требуется создавать элементы пользовательского интерфейса, такие как выпадающие списки, селекторы или формы, которые позволяют пользователям выбирать календари, валюты, часовые пояса или другие параметры локализации. Чтобы создать эти компоненты, необходимо знать, какие значения поддерживаются в среде JavaScript.

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

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

Что возвращает Intl.supportedValuesOf

Метод Intl.supportedValuesOf() принимает одну строку в качестве параметра, которая указывает, какой тип значений нужно вернуть. Он возвращает массив строк, представляющих поддерживаемые значения для указанного типа.

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Вывод: ["buddhist", "chinese", "coptic", "dangi", ...]

Метод поддерживает шесть различных типов ключей:

  • "calendar" возвращает поддерживаемые системы календарей
  • "currency" возвращает поддерживаемые коды валют
  • "timeZone" возвращает поддерживаемые идентификаторы часовых поясов
  • "numberingSystem" возвращает поддерживаемые системы нумерации
  • "collation" возвращает поддерживаемые типы сортировки
  • "unit" возвращает поддерживаемые единицы измерения

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

Если вы передадите недопустимый ключ, метод выбросит ошибку RangeError:

try {
  Intl.supportedValuesOf("invalid");
} catch (error) {
  console.error(error.name);
  // Вывод: "RangeError"
}

Эта ошибка указывает на то, что вы использовали ключ, который метод не распознает.

Поддерживаемые календари

Системы календарей определяют, как рассчитываются и отображаются даты. Разные культуры используют разные системы календарей, и JavaScript поддерживает многие из них через API Intl.

Ключ "calendar" возвращает все системы календарей, поддерживаемые средой JavaScript:

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Вывод: ["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));
// Вывод: "October 15, 2025"

console.log(islamicFormat.format(date));
// Вывод: "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);
  // Создаёт опции вроде "Григорианский календарь", "Исламский календарь" и т.д.
});

Это отображает описательные названия вместо технических идентификаторов.

Получение поддерживаемых валют

Коды валют идентифицируют денежные системы, используемые по всему миру. JavaScript поддерживает сотни кодов валют на основе стандарта ISO 4217.

Ключ "currency" возвращает все коды валют, поддерживаемые средой JavaScript:

const currencies = Intl.supportedValuesOf("currency");
console.log(currencies.length);
// Вывод: обычно более 300

console.log(currencies.slice(0, 10));
// Вывод: ["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));
// Вывод: "$1,234.56"

console.log(eurFormat.format(amount));
// Вывод: "€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);
// Вывод: ["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}`);
});
// Вывод:
// USD: US Dollar
// EUR: Euro
// GBP: British Pound
// JPY: Japanese Yen

Это обеспечивает лучший пользовательский опыт, показывая, что означает каждый код.

Получение поддерживаемых часовых поясов

Часовые пояса представляют географические регионы, которые используют одно и то же стандартное время. JavaScript поддерживает сотни идентификаторов часовых поясов на основе базы данных часовых поясов IANA.

Ключ "timeZone" возвращает все идентификаторы часовых поясов, поддерживаемые средой JavaScript:

const timeZones = Intl.supportedValuesOf("timeZone");
console.log(timeZones.length);
// Вывод: обычно более 400

console.log(timeZones.slice(0, 10));
// Вывод: ["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));
// Вывод: "15 октября 2025 г., 8:00 AM EDT"

console.log(tokyoFormat.format(date));
// Вывод: "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));
// Вывод: ["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}`);
});
// Вывод:
// 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));
// Вывод: ["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));
// Вывод: "12,345"

console.log(arabFormat.format(number));
// Вывод: "١٢٬٣٤٥"

console.log(thaiFormat.format(number));
// Вывод: "๑๒,๓๔๕"

Одно и то же числовое значение отображается с разными формами цифр.

Поддерживаемые типы упорядочивания

Типы упорядочивания определяют, как строки сортируются и сравниваются. Разные языки имеют свои правила алфавитного порядка.

Ключ "collation" возвращает все типы упорядочивания, поддерживаемые в среде JavaScript:

const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Вывод: ["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));
// Вывод: ["a", "ä", "z"]

console.log(words.sort(phoneticCollator.compare));
// Вывод: ["a", "ä", "z"]

Разные типы упорядочивания могут давать разные результаты сортировки для одного и того же ввода.

Поддерживаемые единицы измерения

Идентификаторы единиц измерения представляют такие единицы, как метры, галлоны или градусы Цельсия. JavaScript поддерживает множество типов единиц для форматирования измерений.

Ключ "unit" возвращает все идентификаторы единиц измерения, поддерживаемые в среде JavaScript:

const units = Intl.supportedValuesOf("unit");
console.log(units.slice(0, 10));
// Вывод: ["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));
// Вывод: "1,000 м"

console.log(kilometerFormat.format(1));
// Вывод: "1 км"

Единица измерения определяет, какое сокращение или символ отображается вместе с числом.

Вы можете комбинировать единицы, используя формат "unit1-per-unit2":

const speed = 100;

const speedFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer-per-hour"
});

console.log(speedFormat.format(speed));
// Вывод: "100 км/ч"

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

Создание динамических пользовательских интерфейсов

Основной случай использования Intl.supportedValuesOf() — это создание пользовательских интерфейсов, которые адаптируются к текущей среде JavaScript. Вместо жесткого кодирования опций запросите поддерживаемые значения во время выполнения.

Этот пример создает форму настроек, где пользователи могут выбрать предпочитаемый календарь, валюту и часовой пояс:

function buildSettingsForm() {
  const form = document.createElement("form");

  // Выбор календаря
  const calendarSelect = buildSelector(
    "calendar",
    Intl.supportedValuesOf("calendar")
  );
  form.appendChild(createFormGroup("Календарь", calendarSelect));

  // Выбор валюты
  const currencies = ["USD", "EUR", "GBP", "JPY", "CNY"];
  const currencySelect = buildSelector("currency", currencies);
  form.appendChild(createFormGroup("Валюта", currencySelect));

  // Выбор часового пояса
  const timeZones = Intl.supportedValuesOf("timeZone");
  const timeZoneSelect = buildSelector("timeZone", timeZones);
  form.appendChild(createFormGroup("Часовой пояс", 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("Исламский календарь поддерживается");
} else {
  console.log("Исламский календарь не поддерживается");
}

Этот шаблон работает для любого типа значения:

function isValueSupported(type, value) {
  try {
    const supported = Intl.supportedValuesOf(type);
    return supported.includes(value);
  } catch (error) {
    return false;
  }
}

console.log(isValueSupported("currency", "USD"));
// Вывод: true

console.log(isValueSupported("timeZone", "America/New_York"));
// Вывод: true

Блок try-catch обрабатывает среды, где Intl.supportedValuesOf() недоступен.

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

async function ensureCalendarSupport(calendar) {
  if (!isValueSupported("calendar", calendar)) {
    console.log(`Загрузка полифила для календаря ${calendar}`);
    await import("./calendar-polyfill.js");
  }
}

await ensureCalendarSupport("persian");

Это загружает дополнительный код только при необходимости.