API Intl.Locale
Analiza, manipula y consulta identificadores de locale con objetos JavaScript estructurados
Introducción
Al crear aplicaciones para múltiples idiomas y regiones, te encuentras con identificadores de locale como en-US, fr-FR o zh-Hans-CN. Estas cadenas aparecen en APIs del navegador, encabezados HTTP y preferencias de usuario. Codifican información sobre idioma, región, sistema de escritura y preferencias de formato.
La API Intl.Locale transforma estas cadenas opacas en objetos estructurados que puedes inspeccionar y manipular. En lugar de analizar cadenas manualmente o adivinar qué significa zh-Hans-CN, creas un objeto locale y lees sus propiedades directamente.
Esta guía explica cómo funcionan los identificadores de locale, cómo usar la API Intl.Locale para trabajar con ellos y cuándo los objetos locale estructurados ayudan a resolver problemas reales.
Comprender los identificadores de locale
Un identificador de locale es una cadena que especifica preferencias culturales para formatear fechas, números, monedas y texto. El identificador contiene múltiples componentes separados por guiones.
La estructura más común sigue el estándar BCP 47:
language-script-region-variant-extensions
Cada componente es opcional excepto el código de idioma.
Códigos de idioma
Los códigos de idioma utilizan dos o tres letras de ISO 639. Ejemplos comunes:
enpara inglésespara españolfrpara francésdepara alemánjapara japonészhpara chinoarpara árabe
El código de idioma siempre está en minúsculas y aparece primero en el identificador.
Códigos de región
Los códigos de región especifican áreas geográficas utilizando dos letras mayúsculas de ISO 3166-1. Indican qué variante de un idioma usar:
en-USpara inglés americanoen-GBpara inglés británicoes-ESpara español europeoes-MXpara español mexicanofr-FRpara francés hablado en Franciafr-CApara francés canadiense
Los códigos de región cambian las convenciones de formato. El inglés americano usa fechas MM/DD/YYYY, mientras que el inglés británico usa DD/MM/YYYY.
Códigos de script
Los códigos de script especifican el sistema de escritura usando cuatro letras con la primera letra en mayúscula. Son importantes para idiomas escritos en múltiples scripts:
zh-Hanspara caracteres chinos simplificadoszh-Hantpara caracteres chinos tradicionalessr-Cyrlpara serbio en script cirílicosr-Latnpara serbio en script latino
La mayoría de los locales omiten el código de script porque el idioma implica un script predeterminado. El inglés usa el script latino por defecto, por lo que escribes en en lugar de en-Latn.
Etiquetas de extensión
Las etiquetas de extensión agregan preferencias de formato a los identificadores de locale. Comienzan con -u- seguido de pares clave-valor:
en-US-u-ca-gregory-nu-latn-hc-h12
Claves de extensión comunes:
capara sistema de calendario (gregory,buddhist,islamic)nupara sistema de numeración (latn,arab,hanidec)hcpara ciclo horario (h12,h23,h11,h24)
Las extensiones personalizan cómo los formateadores muestran los datos sin cambiar el idioma o la región.
Crear objetos locale
El constructor Intl.Locale acepta una cadena identificadora de locale y devuelve un objeto estructurado:
const locale = new Intl.Locale("en-US");
console.log(locale.language); // "en"
console.log(locale.region); // "US"
También puedes pasar un objeto de opciones para sobrescribir o agregar propiedades:
const locale = new Intl.Locale("en", {
region: "GB",
hourCycle: "h23"
});
console.log(locale.baseName); // "en-GB"
console.log(locale.hourCycle); // "h23"
El constructor lanza un RangeError si el identificador no es válido:
try {
const invalid = new Intl.Locale("invalid-locale-code");
} catch (error) {
console.error(error.message); // "invalid language subtag: invalid"
}
Esta validación garantiza que detectes identificadores de locale mal formados antes de pasarlos a los formateadores.
Leer propiedades de locale
Los objetos locale exponen propiedades que corresponden a componentes de la cadena identificadora. Todas las propiedades son de solo lectura.
Propiedades principales
La propiedad language devuelve el código de idioma:
const locale = new Intl.Locale("fr-CA");
console.log(locale.language); // "fr"
La propiedad region devuelve el código de región:
const locale = new Intl.Locale("fr-CA");
console.log(locale.region); // "CA"
La propiedad script devuelve el código de escritura si está presente:
const locale = new Intl.Locale("zh-Hans-CN");
console.log(locale.script); // "Hans"
La propiedad baseName devuelve el identificador principal completo sin extensiones:
const locale = new Intl.Locale("en-US-u-ca-gregory-nu-latn");
console.log(locale.baseName); // "en-US"
Utiliza baseName cuando necesites el idioma y la región pero quieras ignorar las preferencias de formato.
Propiedades de extensión
Las propiedades de extensión devuelven valores de la etiqueta de extensión -u- o undefined si no se especifica.
La propiedad calendar devuelve el sistema de calendario:
const locale = new Intl.Locale("ar-SA-u-ca-islamic");
console.log(locale.calendar); // "islamic"
La propiedad numberingSystem devuelve el sistema de numeración:
const locale = new Intl.Locale("ar-EG-u-nu-arab");
console.log(locale.numberingSystem); // "arab"
La propiedad hourCycle devuelve la preferencia de ciclo horario:
const locale = new Intl.Locale("en-US-u-hc-h23");
console.log(locale.hourCycle); // "h23"
La propiedad caseFirst devuelve la preferencia de mayúsculas y minúsculas para la intercalación:
const locale = new Intl.Locale("en-US-u-kf-upper");
console.log(locale.caseFirst); // "upper"
La propiedad numeric indica si la intercalación numérica está habilitada:
const locale = new Intl.Locale("en-US-u-kn-true");
console.log(locale.numeric); // true
Estas propiedades te permiten inspeccionar las preferencias de formato sin analizar manualmente la cadena de extensión.
Consulta de información de configuración regional
La API Intl.Locale proporciona métodos que devuelven arrays de opciones disponibles para una configuración regional. Estos métodos ayudan a construir interfaces de usuario y validar opciones de formato.
Calendarios disponibles
El método getCalendars() devuelve los sistemas de calendario comúnmente utilizados para la configuración regional:
const locale = new Intl.Locale("th-TH");
const calendars = locale.getCalendars();
console.log(calendars); // ["buddhist", "gregory"]
El primer elemento es el calendario predeterminado. Las configuraciones regionales tailandesas utilizan por defecto el calendario budista, pero también usan el calendario gregoriano.
Colaciones disponibles
El método getCollations() devuelve tipos de colación para ordenar cadenas:
const locale = new Intl.Locale("de-DE");
const collations = locale.getCollations();
console.log(collations); // ["phonebk", "emoji", "eor"]
El alemán tiene una colación de guía telefónica que ordena las cadenas de manera diferente a la colación Unicode estándar.
Ciclos horarios disponibles
El método getHourCycles() devuelve formatos de ciclo horario:
const locale = new Intl.Locale("en-US");
const hourCycles = locale.getHourCycles();
console.log(hourCycles); // ["h12"]
El inglés americano utiliza el formato de 12 horas por defecto. Muchas otras configuraciones regionales devuelven ["h23"] para el formato de 24 horas.
Sistemas de numeración disponibles
El método getNumberingSystems() devuelve los sistemas de numeración comúnmente utilizados para la configuración regional:
const locale = new Intl.Locale("ar-EG");
const numberingSystems = locale.getNumberingSystems();
console.log(numberingSystems); // ["arab", "latn"]
Las configuraciones regionales árabes a menudo admiten tanto los numerales arábigo-índicos como los numerales latinos.
Dirección del texto
El método getTextInfo() devuelve información sobre el orden del texto:
const locale = new Intl.Locale("ar-SA");
const textInfo = locale.getTextInfo();
console.log(textInfo.direction); // "rtl"
Los idiomas de derecha a izquierda como el árabe y el hebreo devuelven "rtl". Los idiomas de izquierda a derecha devuelven "ltr".
Convenciones de semana
El método getWeekInfo() devuelve la estructura de la semana para la configuración regional:
const locale = new Intl.Locale("en-US");
const weekInfo = locale.getWeekInfo();
console.log(weekInfo.firstDay); // 7 (Sunday)
console.log(weekInfo.weekend); // [6, 7] (Saturday, Sunday)
console.log(weekInfo.minimalDays); // 1
Las convenciones de semana varían según la región. Las semanas americanas comienzan el domingo, mientras que la mayoría de las semanas europeas comienzan el lunes.
Zonas horarias
El método getTimeZones() devuelve las zonas horarias para la región de la configuración regional:
const locale = new Intl.Locale("en-US");
const timeZones = locale.getTimeZones();
console.log(timeZones); // ["America/New_York", "America/Chicago", ...]
Este método devuelve identificadores de zona horaria IANA para el código de región.
Maximizando identificadores de locale
El método maximize() añade subetiquetas probables para crear un identificador completo. Infiere los códigos de escritura y región faltantes basándose en datos lingüísticos.
Cuando especificas solo un código de idioma, maximize() añade el sistema de escritura y la región más comunes:
const locale = new Intl.Locale("en");
const maximized = locale.maximize();
console.log(maximized.baseName); // "en-Latn-US"
El inglés utiliza por defecto el alfabeto latino y la región de Estados Unidos porque son las asociaciones más comunes.
La maximización del chino depende del sistema de escritura:
const simplified = new Intl.Locale("zh-Hans");
const maximized = simplified.maximize();
console.log(maximized.baseName); // "zh-Hans-CN"
const traditional = new Intl.Locale("zh-Hant");
const maximizedTrad = traditional.maximize();
console.log(maximizedTrad.baseName); // "zh-Hant-TW"
El chino simplificado se asocia con China, mientras que el chino tradicional se asocia con Taiwán.
Utiliza maximize() al normalizar entradas de usuario o comparar identificadores de configuración regional. Hace explícita la información implícita.
Minimizando identificadores de configuración regional
El método minimize() elimina subetiquetas redundantes para crear el identificador equivalente más corto. Elimina los códigos de escritura y región cuando coinciden con los valores predeterminados probables.
Cuando una configuración regional utiliza el sistema de escritura y la región predeterminados, minimize() los elimina:
const locale = new Intl.Locale("en-Latn-US");
const minimized = locale.minimize();
console.log(minimized.baseName); // "en"
El alfabeto latino y la región de Estados Unidos son valores predeterminados para el inglés, por lo que pueden eliminarse sin perder información.
Para configuraciones regionales con regiones no predeterminadas, minimize() mantiene la región:
const locale = new Intl.Locale("en-Latn-GB");
const minimized = locale.minimize();
console.log(minimized.baseName); // "en-GB"
El inglés británico necesita el código de región porque difiere del predeterminado.
Utiliza minimize() para crear identificadores compactos para almacenamiento o URLs mientras preservas el significado.
Convirtiendo a cadenas
El método toString() devuelve el identificador de configuración regional completo incluyendo extensiones:
const locale = new Intl.Locale("en-US", {
calendar: "gregory",
numberingSystem: "latn",
hourCycle: "h12"
});
console.log(locale.toString()); // "en-US-u-ca-gregory-hc-h12-nu-latn"
La representación en cadena es válida para pasarla a otras APIs de Intl o almacenarla como datos de configuración.
También puedes convertir objetos locale a cadenas implícitamente:
const locale = new Intl.Locale("fr-FR");
const formatter = new Intl.DateTimeFormat(locale);
El constructor DateTimeFormat acepta objetos locale directamente y llama a toString() internamente.
Casos de uso prácticos
La API Intl.Locale resuelve varios problemas comunes al construir aplicaciones internacionalizadas.
Construcción de selectores de locale
Los selectores de locale permiten a los usuarios elegir su idioma y región. La API Intl.Locale ayuda a analizar y validar las selecciones de usuario:
function createLocaleSelector(locales) {
const options = locales.map(identifier => {
const locale = new Intl.Locale(identifier);
const displayName = new Intl.DisplayNames([identifier], { type: "language" });
return {
value: locale.toString(),
label: displayName.of(locale.language),
region: locale.region
};
});
return options;
}
const options = createLocaleSelector(["en-US", "en-GB", "fr-FR", "es-MX"]);
console.log(options);
// [
// { value: "en-US", label: "English", region: "US" },
// { value: "en-GB", label: "English", region: "GB" },
// { value: "fr-FR", label: "French", region: "FR" },
// { value: "es-MX", label: "Spanish", region: "MX" }
// ]
Validación de entrada de locale
Al aceptar identificadores de locale desde entrada de usuario o archivos de configuración, valídalos antes de usarlos:
function validateLocale(identifier) {
try {
const locale = new Intl.Locale(identifier);
return {
valid: true,
locale: locale.toString(),
language: locale.language,
region: locale.region
};
} catch (error) {
return {
valid: false,
error: error.message
};
}
}
console.log(validateLocale("en-US")); // { valid: true, locale: "en-US", ... }
console.log(validateLocale("invalid")); // { valid: false, error: "..." }
Extracción de idioma para respaldos
Al implementar cadenas de respaldo de idioma, extrae el código de idioma sin la región:
function getLanguageFallback(identifier) {
const locale = new Intl.Locale(identifier);
const fallbacks = [locale.toString()];
if (locale.region) {
const languageOnly = new Intl.Locale(locale.language);
fallbacks.push(languageOnly.toString());
}
fallbacks.push("en");
return fallbacks;
}
console.log(getLanguageFallback("fr-CA"));
// ["fr-CA", "fr", "en"]
Esto crea una cadena de respaldo que intenta el locale específico, luego el idioma sin región y finalmente el idioma predeterminado.
Configuración de formateadores
Utiliza objetos locale para configurar formateadores Intl con preferencias específicas:
function createFormatter(baseLocale, options = {}) {
const locale = new Intl.Locale(baseLocale, {
calendar: options.calendar || "gregory",
numberingSystem: options.numberingSystem || "latn",
hourCycle: options.hourCycle || "h23"
});
return {
date: new Intl.DateTimeFormat(locale),
number: new Intl.NumberFormat(locale),
locale: locale.toString()
};
}
const formatter = createFormatter("ar-SA", {
calendar: "islamic",
numberingSystem: "arab"
});
console.log(formatter.locale); // "ar-SA-u-ca-islamic-nu-arab"
Detección de preferencias de usuario
Las API del navegador proporcionan cadenas de locale que puedes analizar para comprender las preferencias del usuario:
function getUserPreferences() {
const userLocale = new Intl.Locale(navigator.language);
const hourCycles = userLocale.getHourCycles();
const calendars = userLocale.getCalendars();
const textInfo = userLocale.getTextInfo();
return {
language: userLocale.language,
region: userLocale.region,
preferredHourCycle: hourCycles[0],
preferredCalendar: calendars[0],
textDirection: textInfo.direction
};
}
const preferences = getUserPreferences();
console.log(preferences);
// { language: "en", region: "US", preferredHourCycle: "h12", ... }
Esto crea un perfil de preferencias de usuario basado en la configuración de su navegador.
Compatibilidad con navegadores
La API Intl.Locale funciona en todos los navegadores modernos. Chrome, Firefox, Safari y Edge proporcionan compatibilidad completa para el constructor, propiedades y métodos descritos en esta guía.
Los métodos más recientes como getCalendars(), getCollations(), getHourCycles(), getNumberingSystems(), getTextInfo(), getTimeZones() y getWeekInfo() requieren versiones recientes del navegador. Consulta las tablas de compatibilidad del navegador antes de usar estos métodos si das soporte a navegadores más antiguos.
Node.js admite la API Intl.Locale a partir de la versión 12, con compatibilidad completa de métodos en la versión 18 y posteriores.
Resumen
La API Intl.Locale transforma cadenas identificadoras de locale en objetos estructurados que puedes inspeccionar y manipular. En lugar de analizar cadenas manualmente, creas objetos locale y lees sus propiedades.
Conceptos principales:
- Los identificadores de configuración regional contienen componentes de idioma, escritura, región y extensión
- El constructor
Intl.Localevalida identificadores y crea objetos - Las propiedades como
language,regionycalendarproporcionan acceso estructurado - Los métodos como
getCalendars()ygetHourCycles()devuelven las opciones disponibles - Los métodos
maximize()yminimize()normalizan identificadores - Los objetos locale funcionan directamente con otras API de
Intl
Usa la API Intl.Locale al construir selectores de configuración regional, validar entrada de usuario, implementar cadenas de respaldo o configurar formateadores. Proporciona una forma estándar de trabajar con identificadores de configuración regional en aplicaciones JavaScript.