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 crear aplicaciones internacionalizadas, a menudo necesitas crear elementos de interfaz de usuario como menús 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 JavaScript.
En lugar de mantener listas codificadas que quedan obsoletas o contienen valores que el navegador no admite, JavaScript proporciona un método para descubrir los valores compatibles en tiempo de ejecución. Esto garantiza 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 compatibles. Puedes consultar este método para obtener calendarios, monedas, zonas horarias, sistemas de numeración, tipos de intercalación y unidades de medida que el entorno JavaScript admite.
Qué devuelve Intl.supportedValuesOf
El método Intl.supportedValuesOf() acepta un único parámetro de cadena que especifica qué tipo de valores devolver. Devuelve un array de cadenas que representan los valores compatibles para ese tipo.
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", ...]
El método admite seis tipos de clave diferentes:
"calendar"devuelve los sistemas de calendario compatibles"currency"devuelve los códigos de moneda compatibles"timeZone"devuelve los identificadores de zona horaria compatibles"numberingSystem"devuelve los sistemas de numeración compatibles"collation"devuelve los tipos de intercalación compatibles"unit"devuelve las unidades de medida compatibles
El array devuelto siempre está ordenado en orden alfabético 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);
// Output: "RangeError"
}
Este error indica que utilizaste 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);
// Output: ["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 chino tradicional"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));
// Output: "October 15, 2025"
console.log(islamicFormat.format(date));
// Output: "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:
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.
});
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);
// Output: typically over 300
console.log(currencies.slice(0, 10));
// Output: ["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"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 usar:
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"
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);
// Output: ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"]
Esto garantiza que solo ofrezcas monedas que cumplan tus requisitos y sean compatibles con el navegador.
Mostrar nombres de monedas
Al crear 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 qué representa cada código.
Obtener zonas horarias compatibles
Las zonas horarias representan regiones geográficas que observan la misma hora estándar. JavaScript admite cientos de identificadores de zona horaria basados en la base de datos de zonas horarias IANA.
La clave "timeZone" devuelve todos los identificadores de zona horaria compatibles con el entorno 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"]
Los identificadores de zona horaria siguen el formato Continent/City, 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.
Crear selectores de zona horaria
Los selectores de zona horaria necesitan presentar cientos de opciones de manera que los usuarios puedan entender. 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 que los usuarios encuentren su ubicación.
Puedes mejorar aún más la experiencia del 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 comprender la diferencia horaria entre zonas.
Obtener 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 números 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
Los diferentes sistemas de numeración muestran el mismo número de forma diferente:
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 intercalación compatibles
Los tipos de intercalación definen cómo se ordenan y comparan las cadenas. Los diferentes idiomas tienen reglas distintas para el orden alfabético.
La clave "collation" devuelve todos los tipos de intercalación compatibles con el entorno JavaScript:
const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Output: ["big5han", "compat", "dict", "direct", "ducet", "emoji",
// "eor", "gb2312", "phonebk", "phonetic"]
Los tipos de intercalación comunes incluyen:
"standard"para la intercalación predeterminada de cada idioma"phonetic"para ordenación fonética"pinyin"para ordenación por pinyin chino"emoji"para ordenación de emojis
La intercalació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));
// Output: ["a", "ä", "z"]
console.log(words.sort(phoneticCollator.compare));
// Output: ["a", "ä", "z"]
Los diferentes tipos de intercalación pueden producir órdenes de clasificación distintos 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));
// Output: ["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 medidas, 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));
// Output: "1,000 m"
console.log(kilometerFormat.format(1));
// Output: "1 km"
La unidad determina qué abreviatura o símbolo aparece con el número.
Puedes combinar unidades usando 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));
// Output: "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 construir interfaces de usuario que se adapten al entorno JavaScript actual. En lugar de codificar opciones de forma fija, consulta los valores soportados 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");
// 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());
Esto crea una interfaz de configuración completa usando solo valores que el navegador soporta.
Uso de valores soportados para detección de características
Puedes usar Intl.supportedValuesOf() para detectar si valores específicos están soportados antes de usarlos. Esto ayuda a implementar estrategias de mejora progresiva y fallback.
Verifica si un calendario específico está soportado:
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"));
// Output: true
console.log(isValueSupported("timeZone", "America/New_York"));
// Output: true
El bloque try-catch maneja entornos donde Intl.supportedValuesOf() no está disponible.
Puedes usar esto para 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.