Cómo obtener la lista de calendarios, monedas y zonas horarias compatibles
Descubre qué valores de internacionalización admite tu entorno JavaScript
Introducción
Al construir aplicaciones internacionalizadas, a menudo necesitas crear elementos de interfaz de usuario como desplegables, selectores o formularios que permitan a los usuarios elegir calendarios, monedas, zonas horarias u otras opciones de localización. Para construir estos componentes, necesitas saber qué valores admite el entorno de JavaScript.
En lugar de mantener listas codificadas que se vuelven obsoletas o contienen valores que el navegador no admite, JavaScript proporciona un método para descubrir los valores admitidos en tiempo de ejecución. Esto asegura que tu aplicación solo ofrezca opciones que funcionen correctamente en el entorno del usuario.
El método Intl.supportedValuesOf() devuelve listas de valores de internacionalización admitidos. Puedes consultar este método para obtener calendarios, monedas, zonas horarias, sistemas de numeración, tipos de ordenación y unidades de medida que el entorno de JavaScript admite.
Qué devuelve Intl.supportedValuesOf
El método Intl.supportedValuesOf() acepta un único parámetro de tipo string que especifica qué tipo de valores devolver. Retorna un array de strings que representan los valores admitidos para ese tipo.
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Salida: ["buddhist", "chinese", "coptic", "dangi", ...]
El método admite seis tipos diferentes de claves:
"calendar"devuelve los sistemas de calendario admitidos"currency"devuelve los códigos de moneda admitidos"timeZone"devuelve los identificadores de zona horaria admitidos"numberingSystem"devuelve los sistemas de numeración admitidos"collation"devuelve los tipos de ordenación admitidos"unit"devuelve las unidades de medida admitidas
El array devuelto siempre está ordenado alfabéticamente de forma ascendente, no contiene valores duplicados y utiliza identificadores canónicos según los estándares Unicode.
Si pasas una clave no válida, el método lanza un RangeError:
try {
Intl.supportedValuesOf("invalid");
} catch (error) {
console.error(error.name);
// Salida: "RangeError"
}
Este error indica que has utilizado una clave que el método no reconoce.
Obtener calendarios compatibles
Los sistemas de calendario definen cómo se calculan y muestran las fechas. Diferentes culturas utilizan diferentes sistemas de calendario, y JavaScript admite muchos de ellos a través de la API Intl.
La clave "calendar" devuelve todos los sistemas de calendario compatibles con el entorno JavaScript:
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Resultado: ["buddhist", "chinese", "coptic", "dangi", "ethioaa",
// "ethiopic", "gregory", "hebrew", "indian", "islamic",
// "islamic-civil", "islamic-rgsa", "islamic-tbla",
// "islamic-umalqura", "iso8601", "japanese", "persian",
// "roc"]
El calendario más común es "gregory", que representa el calendario gregoriano utilizado en la mayor parte del mundo. Otros calendarios incluyen:
"buddhist"para el calendario budista tailandés"chinese"para el calendario tradicional chino"islamic"para el calendario islámico Hijri"hebrew"para el calendario hebreo"japanese"para el calendario japonés con nombres de era
Cada calendario afecta cómo se formatean y calculan las fechas. Cuando utilizas Intl.DateTimeFormat con un calendario específico, las fechas aparecen según las reglas de ese calendario:
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));
// Resultado: "October 15, 2025"
console.log(islamicFormat.format(date));
// Resultado: "Rabi' II 13, 1447 AH"
La misma fecha de JavaScript aparece de manera diferente cuando se formatea con diferentes calendarios.
Usar calendarios compatibles para crear selectores
Al crear un selector de calendario en tu interfaz de usuario, consulta los calendarios compatibles y crea opciones para cada uno:
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);
Esto crea un menú desplegable que contiene solo los calendarios que funcionan en el entorno actual.
Puedes mejorar este selector utilizando Intl.DisplayNames para mostrar nombres de calendario legibles para humanos:
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);
// Crea opciones como "Calendario gregoriano", "Calendario islámico", etc.
});
Esto muestra nombres descriptivos en lugar de identificadores técnicos.
Obtener monedas compatibles
Los códigos de moneda identifican los sistemas monetarios utilizados en todo el mundo. JavaScript admite cientos de códigos de moneda basados en el estándar ISO 4217.
La clave "currency" devuelve todos los códigos de moneda compatibles con el entorno JavaScript:
const currencies = Intl.supportedValuesOf("currency");
console.log(currencies.length);
// Resultado: típicamente más de 300
console.log(currencies.slice(0, 10));
// Resultado: ["ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK"]
Los códigos de moneda utilizan tres letras mayúsculas. Ejemplos comunes incluyen:
"USD"para Dólar estadounidense"EUR"para Euro"GBP"para Libra esterlina británica"JPY"para Yen japonés"CNY"para Yuan chino
La lista incluye tanto monedas actuales como algunas monedas históricas que ya no están en circulación.
Al formatear valores de moneda, debes especificar qué moneda utilizar:
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));
// Resultado: "$1,234.56"
console.log(eurFormat.format(amount));
// Resultado: "€1,234.56"
El código de moneda determina qué símbolo aparece y cómo se formatea el valor.
Filtrar monedas para selección del usuario
La mayoría de las aplicaciones solo necesitan mostrar monedas actuales y de uso común. Puedes filtrar la lista de monedas compatibles para incluir solo las relevantes para tus usuarios:
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);
// Resultado: ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"]
Esto asegura que solo ofrezcas monedas que cumplan con tus requisitos y sean compatibles con el navegador.
Mostrar nombres de monedas
Al construir un selector de monedas, muestra nombres descriptivos en lugar de códigos de tres letras:
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
Esto proporciona una mejor experiencia de usuario al mostrar lo que representa cada código.
Obtener zonas horarias compatibles
Las zonas horarias representan regiones geográficas que observan el mismo horario estándar. JavaScript admite cientos de identificadores de zonas horarias basados en la base de datos de zonas horarias IANA.
La clave "timeZone" devuelve todos los identificadores de zonas horarias compatibles con el entorno JavaScript:
const timeZones = Intl.supportedValuesOf("timeZone");
console.log(timeZones.length);
// Output: típicamente más de 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"]
Los identificadores de zonas horarias siguen el formato Continente/Ciudad, como "America/New_York" o "Europe/London". Algunos identificadores incluyen componentes adicionales como "America/Indiana/Indianapolis".
Al formatear fechas y horas, la zona horaria afecta qué hora local aparece:
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"
El mismo momento en el tiempo aparece como diferentes horas locales dependiendo de la zona horaria.
Construcción de selectores de zona horaria
Los selectores de zona horaria necesitan presentar cientos de opciones de manera comprensible para los usuarios. Agrupa las zonas horarias por región para facilitar la selección:
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"]
Esta organización agrupa las zonas horarias por continente, facilitando a los usuarios encontrar su ubicación.
Puedes mejorar aún más la experiencia de usuario mostrando el desplazamiento actual para cada zona horaria:
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
Mostrar los desplazamientos ayuda a los usuarios a entender la diferencia horaria entre zonas.
Obtención de sistemas de numeración compatibles
Los sistemas de numeración definen cómo se muestran los dígitos. Aunque la mayoría de las aplicaciones utilizan los numerales arábigos estándar (0-9), muchos idiomas tienen sus propios sistemas de numeración tradicionales.
La clave "numberingSystem" devuelve todos los sistemas de numeración compatibles con el entorno JavaScript:
const numberingSystems = Intl.supportedValuesOf("numberingSystem");
console.log(numberingSystems.slice(0, 10));
// Output: ["adlm", "ahom", "arab", "arabext", "armn", "armnlow",
// "bali", "beng", "bhks", "brah"]
Los sistemas de numeración comunes incluyen:
"latn"para dígitos latinos estándar (0-9)"arab"para dígitos arábigo-índicos"thai"para dígitos tailandeses"deva"para dígitos devanagari utilizados en hindi
Diferentes sistemas de numeración muestran el mismo número de manera distinta:
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: "๑๒,๓๔๕"
El mismo valor numérico aparece con diferentes formas de dígitos.
Obtener tipos de colación compatibles
Los tipos de colación definen cómo se ordenan y comparan las cadenas de texto. Diferentes idiomas tienen diferentes reglas para el ordenamiento alfabético.
La clave "collation" devuelve todos los tipos de colación compatibles con el entorno JavaScript:
const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Salida: ["big5han", "compat", "dict", "direct", "ducet", "emoji",
// "eor", "gb2312", "phonebk", "phonetic"]
Los tipos de colación comunes incluyen:
"standard"para la colación predeterminada de cada idioma"phonetic"para ordenamiento fonético"pinyin"para ordenamiento pinyin chino"emoji"para ordenamiento de emojis
La colación afecta cómo se ordenan los arrays de cadenas:
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));
// Salida: ["a", "ä", "z"]
console.log(words.sort(phoneticCollator.compare));
// Salida: ["a", "ä", "z"]
Diferentes tipos de colación pueden producir diferentes órdenes de clasificación para la misma entrada.
Obtener unidades compatibles
Los identificadores de unidad representan unidades de medida como metros, galones o grados Celsius. JavaScript admite muchos tipos de unidades para formatear mediciones.
La clave "unit" devuelve todos los identificadores de unidad compatibles con el entorno JavaScript:
const units = Intl.supportedValuesOf("unit");
console.log(units.slice(0, 10));
// Salida: ["acre", "bit", "byte", "celsius", "centimeter", "day",
// "degree", "fahrenheit", "fluid-ounce", "foot"]
Las unidades comunes incluyen:
- Longitud:
"meter","kilometer","mile","foot" - Peso:
"gram","kilogram","pound","ounce" - Temperatura:
"celsius","fahrenheit" - Volumen:
"liter","gallon" - Digital:
"byte","kilobyte","megabyte"
Al formatear mediciones, especifica la unidad a utilizar:
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));
// Salida: "1,000 m"
console.log(kilometerFormat.format(1));
// Salida: "1 km"
La unidad determina qué abreviatura o símbolo aparece con el número.
Puedes combinar unidades utilizando el formato "unit1-per-unit2":
const speed = 100;
const speedFormat = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilometer-per-hour"
});
console.log(speedFormat.format(speed));
// Salida: "100 km/h"
Esto crea unidades compuestas como kilómetros por hora o millas por galón.
Construcción de interfaces de usuario dinámicas
El caso de uso principal para Intl.supportedValuesOf() es la construcción de interfaces de usuario que se adaptan al entorno JavaScript actual. En lugar de codificar opciones de forma estática, consulta los valores compatibles en tiempo de ejecución.
Este ejemplo crea un formulario de configuración donde los usuarios pueden elegir su calendario, moneda y zona horaria preferidos:
function buildSettingsForm() {
const form = document.createElement("form");
// Selector de calendario
const calendarSelect = buildSelector(
"calendar",
Intl.supportedValuesOf("calendar")
);
form.appendChild(createFormGroup("Calendar", calendarSelect));
// Selector de moneda
const currencies = ["USD", "EUR", "GBP", "JPY", "CNY"];
const currencySelect = buildSelector("currency", currencies);
form.appendChild(createFormGroup("Currency", currencySelect));
// Selector de zona horaria
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());
Esto crea una interfaz de configuración completa utilizando solo valores que el navegador soporta.
Uso de valores compatibles para la detección de características
Puedes utilizar Intl.supportedValuesOf() para detectar si ciertos valores específicos son compatibles antes de usarlos. Esto ayuda a implementar estrategias de mejora progresiva y alternativas de respaldo.
Comprobar si un calendario específico es compatible:
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");
}
Este patrón funciona para cualquier tipo de valor:
function isValueSupported(type, value) {
try {
const supported = Intl.supportedValuesOf(type);
return supported.includes(value);
} catch (error) {
return false;
}
}
console.log(isValueSupported("currency", "USD"));
// Salida: true
console.log(isValueSupported("timeZone", "America/New_York"));
// Salida: true
El bloque try-catch maneja entornos donde Intl.supportedValuesOf() no está disponible.
Puedes usar esto para la carga condicional de polyfills:
async function ensureCalendarSupport(calendar) {
if (!isValueSupported("calendar", calendar)) {
console.log(`Loading polyfill for ${calendar} calendar`);
await import("./calendar-polyfill.js");
}
}
await ensureCalendarSupport("persian");
Esto carga código adicional solo cuando es necesario.