How to get list of supported calendars, currencies, time zones

Discover which internationalization values your JavaScript environment supports

Introduction

When building internationalized applications, you often need to create user interface elements like dropdowns, selectors, or forms that let users choose calendars, currencies, time zones, or other localization options. To build these components, you need to know which values the JavaScript environment supports.

Rather than maintaining hardcoded lists that become outdated or contain values the browser does not support, JavaScript provides a method to discover supported values at runtime. This ensures your application only offers choices that work correctly in the user's environment.

The Intl.supportedValuesOf() method returns lists of supported internationalization values. You can query this method to get calendars, currencies, time zones, numbering systems, collation types, and measurement units that the JavaScript environment supports.

What Intl.supportedValuesOf returns

The Intl.supportedValuesOf() method accepts a single string parameter that specifies which type of values to return. It returns an array of strings representing the supported values for that type.

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", ...]

The method supports six different key types:

  • "calendar" returns supported calendar systems
  • "currency" returns supported currency codes
  • "timeZone" returns supported time zone identifiers
  • "numberingSystem" returns supported numbering systems
  • "collation" returns supported collation types
  • "unit" returns supported measurement units

The returned array is always sorted in ascending alphabetical order, contains no duplicate values, and uses canonical identifiers according to Unicode standards.

If you pass an invalid key, the method throws a RangeError:

try {
  Intl.supportedValuesOf("invalid");
} catch (error) {
  console.error(error.name);
  // Output: "RangeError"
}

This error indicates you used a key that the method does not recognize.

Getting supported calendars

Calendar systems define how dates are calculated and displayed. Different cultures use different calendar systems, and JavaScript supports many of them through the Intl API.

The "calendar" key returns all calendar systems supported by the JavaScript environment:

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"]

The most common calendar is "gregory", which represents the Gregorian calendar used in most of the world. Other calendars include:

  • "buddhist" for the Thai Buddhist calendar
  • "chinese" for the traditional Chinese calendar
  • "islamic" for the Islamic Hijri calendar
  • "hebrew" for the Hebrew calendar
  • "japanese" for the Japanese calendar with era names

Each calendar affects how dates are formatted and calculated. When you use Intl.DateTimeFormat with a specific calendar, dates appear according to that calendar's rules:

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"

The same JavaScript date appears differently when formatted with different calendars.

Using supported calendars to build selectors

When building a calendar selector in your user interface, query the supported calendars and create options for each one:

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);

This creates a dropdown containing only the calendars that work in the current environment.

You can enhance this selector by using Intl.DisplayNames to show human-readable calendar names:

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.
});

This shows descriptive names instead of technical identifiers.

Getting supported currencies

Currency codes identify monetary systems used around the world. JavaScript supports hundreds of currency codes based on the ISO 4217 standard.

The "currency" key returns all currency codes supported by the JavaScript environment:

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"]

Currency codes use three uppercase letters. Common examples include:

  • "USD" for United States Dollar
  • "EUR" for Euro
  • "GBP" for British Pound Sterling
  • "JPY" for Japanese Yen
  • "CNY" for Chinese Yuan

The list includes both current currencies and some historical currencies that are no longer in circulation.

When formatting currency values, you must specify which currency to use:

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"

The currency code determines which symbol appears and how the value is formatted.

Filtering currencies for user selection

Most applications only need to show current, commonly used currencies. You can filter the supported currencies list to include only the ones relevant to your users:

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"]

This ensures you only offer currencies that both meet your requirements and are supported by the browser.

Displaying currency names

When building a currency selector, show descriptive names instead of three-letter codes:

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

This provides a better user experience by showing what each code represents.

Getting supported time zones

Time zones represent geographic regions that observe the same standard time. JavaScript supports hundreds of time zone identifiers based on the IANA time zone database.

The "timeZone" key returns all time zone identifiers supported by the JavaScript environment:

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"]

Time zone identifiers follow the format Continent/City, like "America/New_York" or "Europe/London". Some identifiers include additional components like "America/Indiana/Indianapolis".

When formatting dates and times, the time zone affects which local time appears:

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"

The same moment in time appears as different local times depending on the time zone.

Building time zone selectors

Time zone selectors need to present hundreds of options in a way users can understand. Group time zones by region to make selection easier:

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"]

This organization groups time zones by continent, making it easier for users to find their location.

You can further improve the user experience by showing the current offset for each time zone:

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

Showing offsets helps users understand the time difference between zones.

Getting supported numbering systems

Numbering systems define how digits are displayed. While most applications use the standard Arabic numerals (0-9), many languages have their own traditional numbering systems.

The "numberingSystem" key returns all numbering systems supported by the JavaScript environment:

const numberingSystems = Intl.supportedValuesOf("numberingSystem");
console.log(numberingSystems.slice(0, 10));
// Output: ["adlm", "ahom", "arab", "arabext", "armn", "armnlow",
//          "bali", "beng", "bhks", "brah"]

Common numbering systems include:

  • "latn" for standard Latin digits (0-9)
  • "arab" for Arabic-Indic digits
  • "thai" for Thai digits
  • "deva" for Devanagari digits used in Hindi

Different numbering systems display the same number differently:

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: "๑๒,๓๔๕"

The same numeric value appears with different digit shapes.

Getting supported collation types

Collation types define how strings are sorted and compared. Different languages have different rules for alphabetical ordering.

The "collation" key returns all collation types supported by the JavaScript environment:

const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Output: ["big5han", "compat", "dict", "direct", "ducet", "emoji",
//          "eor", "gb2312", "phonebk", "phonetic"]

Common collation types include:

  • "standard" for the default collation of each language
  • "phonetic" for phonetic ordering
  • "pinyin" for Chinese pinyin ordering
  • "emoji" for emoji sorting

Collation affects how arrays of strings are sorted:

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"]

Different collation types can produce different sort orders for the same input.

Getting supported units

Unit identifiers represent measurement units like meters, gallons, or degrees Celsius. JavaScript supports many unit types for formatting measurements.

The "unit" key returns all unit identifiers supported by the JavaScript environment:

const units = Intl.supportedValuesOf("unit");
console.log(units.slice(0, 10));
// Output: ["acre", "bit", "byte", "celsius", "centimeter", "day",
//          "degree", "fahrenheit", "fluid-ounce", "foot"]

Common units include:

  • Length: "meter", "kilometer", "mile", "foot"
  • Weight: "gram", "kilogram", "pound", "ounce"
  • Temperature: "celsius", "fahrenheit"
  • Volume: "liter", "gallon"
  • Digital: "byte", "kilobyte", "megabyte"

When formatting measurements, specify the unit to use:

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"

The unit determines which abbreviation or symbol appears with the number.

You can combine units using the format "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"

This creates compound units like kilometers per hour or miles per gallon.

Building dynamic user interfaces

The primary use case for Intl.supportedValuesOf() is building user interfaces that adapt to the current JavaScript environment. Rather than hardcoding options, query the supported values at runtime.

This example creates a settings form where users can choose their preferred calendar, currency, and time zone:

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());

This creates a complete settings interface using only values that the browser supports.

Using supported values for feature detection

You can use Intl.supportedValuesOf() to detect whether specific values are supported before using them. This helps implement progressive enhancement and fallback strategies.

Check if a specific calendar is supported:

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");
}

This pattern works for any value type:

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

The try-catch block handles environments where Intl.supportedValuesOf() is not available.

You can use this for conditional loading of polyfills:

async function ensureCalendarSupport(calendar) {
  if (!isValueSupported("calendar", calendar)) {
    console.log(`Loading polyfill for ${calendar} calendar`);
    await import("./calendar-polyfill.js");
  }
}

await ensureCalendarSupport("persian");

This loads additional code only when needed.