Cómo añadir etiquetas probables a locales incompletos
Usa JavaScript para completar identificadores de locale parciales con el script y la región más probables
Introducción
Al trabajar con identificadores de locale, a veces recibes información incompleta. Un usuario podría especificar solo un código de idioma como ja sin indicar el script o la región. Aunque este identificador parcial es válido, carece de la especificidad necesaria para ciertas operaciones como comparar locales o determinar convenciones de formateo.
JavaScript proporciona una forma de completar estos identificadores parciales añadiendo los componentes faltantes más probables. Este proceso utiliza datos de idiomas para inferir el script y la región que los usuarios de ese idioma suelen utilizar.
Esta guía explica qué son las etiquetas probables, cómo las determina JavaScript y cuándo usar esta funcionalidad en tus aplicaciones.
Qué son las etiquetas probables
Las etiquetas probables son los códigos de script y región que aparecen más comúnmente con un idioma determinado. Estas asociaciones provienen de datos de uso real del idioma mantenidos por el Consorcio Unicode.
Por ejemplo, el inglés se escribe típicamente en script latino y se usa más comúnmente en Estados Unidos. Si solo tienes el código de idioma en, las etiquetas probables son Latn para el script y US para la región, lo que te da el identificador completo en-Latn-US.
La probabilidad se basa en poblaciones de hablantes y patrones de uso históricos. El algoritmo siempre devuelve la combinación estadísticamente más común.
Por qué añadir etiquetas probables
Los identificadores de locale parciales funcionan para la mayoría de las operaciones de formateo. Las APIs Intl.DateTimeFormat y Intl.NumberFormat aceptan en y aplicarán valores predeterminados sensatos. Sin embargo, hay situaciones donde tener identificadores completos es necesario.
Comparación de identificadores de configuración regional
Al comparar dos identificadores de configuración regional para ver si se refieren al mismo idioma y región, los identificadores parciales crean ambigüedad. ¿Significa en lo mismo que en-US, o es diferente porque uno especifica una región y el otro no?
Añadir subetiquetas probables elimina esta ambigüedad. Tanto en como en-US se maximizan a en-Latn-US, haciéndolos directamente comparables.
const locale1 = new Intl.Locale("en");
const locale2 = new Intl.Locale("en-US");
console.log(locale1.baseName === locale2.baseName);
// false - they look different
const maximized1 = locale1.maximize();
const maximized2 = locale2.maximize();
console.log(maximized1.baseName === maximized2.baseName);
// true - both are "en-Latn-US"
Almacenamiento de formas canónicas
Al almacenar identificadores de configuración regional en bases de datos o archivos de configuración, usar formas completas garantiza la coherencia. Cada configuración regional francesa se convierte en fr-Latn-FR, cada configuración regional japonesa se convierte en ja-Jpan-JP, y así sucesivamente.
Esta coherencia hace que la búsqueda, el filtrado y la agrupación por configuración regional sean más confiables.
Determinación del comportamiento específico de la escritura
Algunos idiomas utilizan múltiples escrituras, y la escritura afecta la representación del texto, la selección de fuentes y la intercalación. El chino puede escribirse en caracteres simplificados o tradicionales, y el serbio puede usar escritura cirílica o latina.
Añadir subetiquetas probables hace explícita la escritura. Si un usuario proporciona zh sin especificar una escritura, maximizarlo produce zh-Hans-CN, indicando que se esperan caracteres chinos simplificados.
Cómo funciona el algoritmo
El algoritmo de añadir subetiquetas probables utiliza una base de datos de información sobre el uso de idiomas para determinar los componentes faltantes. Esta base de datos es mantenida por el Consorcio Unicode como parte del repositorio común de datos de configuración regional.
El algoritmo examina la información que proporcionas y completa los espacios vacíos:
- Si proporcionas solo un idioma, añade la escritura y la región más comunes para ese idioma
- Si proporcionas un idioma y una escritura, añade la región más común para esa combinación
- Si proporcionas un idioma y una región, añade la escritura más común para esa combinación
- Si proporcionas los tres componentes, permanecen sin cambios
Las decisiones se basan en datos estadísticos sobre el uso de idiomas en todo el mundo.
Uso del método maximize
El método maximize() está disponible en objetos Intl.Locale. Devuelve un nuevo objeto de locale con las subetiquetas probables agregadas al nombre base.
const locale = new Intl.Locale("ja");
const maximized = locale.maximize();
console.log(locale.baseName);
// "ja"
console.log(maximized.baseName);
// "ja-Jpan-JP"
El método no modifica el objeto de locale original. Crea y devuelve uno nuevo.
Ejemplos con diferentes idiomas
Los diferentes idiomas tienen diferentes subetiquetas probables según dónde se hablan principalmente y qué scripts utilizan.
Idiomas europeos
El francés se maximiza a Francia con script latino:
const french = new Intl.Locale("fr");
const maximized = french.maximize();
console.log(maximized.baseName);
// "fr-Latn-FR"
El alemán se maximiza a Alemania con script latino:
const german = new Intl.Locale("de");
const maximized = german.maximize();
console.log(maximized.baseName);
// "de-Latn-DE"
Idiomas con scripts no latinos
El japonés se maximiza a Japón con script japonés:
const japanese = new Intl.Locale("ja");
const maximized = japanese.maximize();
console.log(maximized.baseName);
// "ja-Jpan-JP"
El árabe se maximiza a Egipto con script árabe:
const arabic = new Intl.Locale("ar");
const maximized = arabic.maximize();
console.log(maximized.baseName);
// "ar-Arab-EG"
El chino sin script se maximiza a caracteres simplificados y China:
const chinese = new Intl.Locale("zh");
const maximized = chinese.maximize();
console.log(maximized.baseName);
// "zh-Hans-CN"
Identificadores parciales con regiones
Cuando proporcionas un idioma y una región pero sin script, el algoritmo agrega el script:
const britishEnglish = new Intl.Locale("en-GB");
const maximized = britishEnglish.maximize();
console.log(maximized.baseName);
// "en-Latn-GB"
La región permanece como se especificó. Solo se agrega el script faltante.
Identificadores parciales con scripts
Cuando proporcionas un idioma y un script pero sin región, el algoritmo agrega la región más común para ese script:
const traditionalChinese = new Intl.Locale("zh-Hant");
const maximized = traditionalChinese.maximize();
console.log(maximized.baseName);
// "zh-Hant-TW"
Los caracteres chinos tradicionales se utilizan principalmente en Taiwán, por lo que TW se añade como región.
Las etiquetas de extensión se conservan
Las etiquetas de extensión Unicode especifican preferencias de formato como sistemas de calendario, sistemas de numeración y ciclos horarios. Estas etiquetas aparecen después de -u- en el identificador de configuración regional.
El método maximize() no modifica las etiquetas de extensión. Solo afecta a los componentes de idioma, script y región.
const locale = new Intl.Locale("fr", {
calendar: "gregory",
numberingSystem: "latn",
hourCycle: "h23"
});
console.log(locale.toString());
// "fr-u-ca-gregory-hc-h23-nu-latn"
const maximized = locale.maximize();
console.log(maximized.toString());
// "fr-Latn-FR-u-ca-gregory-hc-h23-nu-latn"
El nombre base cambia de fr a fr-Latn-FR, pero las etiquetas de extensión permanecen idénticas.
Cuándo usar maximize
Utiliza el método maximize() cuando necesites identificadores de configuración regional completos para fines de consistencia o comparación.
Normalización de entrada del usuario
Los usuarios pueden introducir configuraciones regionales en varias formas. Algunos pueden escribir en, otros en-US y otros en-Latn-US. Maximizar todas las entradas crea un formato consistente:
function normalizeLocale(input) {
try {
const locale = new Intl.Locale(input);
const maximized = locale.maximize();
return maximized.baseName;
} catch (error) {
return null;
}
}
console.log(normalizeLocale("en"));
// "en-Latn-US"
console.log(normalizeLocale("en-US"));
// "en-Latn-US"
console.log(normalizeLocale("en-Latn-US"));
// "en-Latn-US"
Las tres entradas producen la misma forma normalizada.
Construcción de cadenas de respaldo de configuración regional
Cuando una configuración regional específica no está disponible, las aplicaciones recurren a configuraciones regionales más generales. Maximizar ayuda a construir estas cadenas correctamente:
function buildFallbackChain(localeString) {
const locale = new Intl.Locale(localeString);
const maximized = locale.maximize();
const chain = [maximized.toString()];
if (maximized.script && maximized.region) {
const withoutRegion = new Intl.Locale(
`${maximized.language}-${maximized.script}`
);
chain.push(withoutRegion.toString());
}
if (maximized.region) {
chain.push(maximized.language);
}
chain.push("en");
return chain;
}
console.log(buildFallbackChain("zh-TW"));
// ["zh-Hant-TW", "zh-Hant", "zh", "en"]
Esto crea un respaldo adecuado desde la configuración regional más específica hasta la más general.
Coincidencia de preferencias del usuario con configuraciones regionales disponibles
Cuando tienes un conjunto de traducciones disponibles y necesitas encontrar la mejor coincidencia para una preferencia del usuario, maximizar ambos lados permite una comparación precisa:
function findBestMatch(userPreference, availableLocales) {
const userMaximized = new Intl.Locale(userPreference).maximize();
const matches = availableLocales.map(available => {
const availableMaximized = new Intl.Locale(available).maximize();
let score = 0;
if (userMaximized.language === availableMaximized.language) score += 1;
if (userMaximized.script === availableMaximized.script) score += 1;
if (userMaximized.region === availableMaximized.region) score += 1;
return { locale: available, score };
});
matches.sort((a, b) => b.score - a.score);
return matches[0].locale;
}
const available = ["en-US", "en-GB", "fr-FR", "de-DE"];
console.log(findBestMatch("en", available));
// "en-US"
La función expande la preferencia del usuario en a en-Latn-US y encuentra la coincidencia más cercana.
Cuándo no usar maximize
No necesitas maximizar las configuraciones regionales antes de pasarlas a las APIs de formato. Los constructores Intl.DateTimeFormat, Intl.NumberFormat y otros de formato manejan correctamente los identificadores parciales.
const date = new Date("2025-03-15");
const partial = new Intl.DateTimeFormat("fr").format(date);
const maximized = new Intl.DateTimeFormat("fr-Latn-FR").format(date);
console.log(partial);
// "15/03/2025"
console.log(maximized);
// "15/03/2025"
Ambos producen una salida idéntica. La especificidad adicional no cambia el comportamiento de formato en este caso.
Utiliza maximize() cuando necesites la información explícita para tu propia lógica, no cuando pases configuraciones regionales a formateadores integrados.
Compatibilidad con navegadores
El método maximize() está disponible en todos los navegadores modernos. Chrome, Firefox, Safari y Edge lo admiten como parte de la API Intl.Locale.
Node.js admite maximize() a partir de la versión 12, con compatibilidad completa en la versión 14 y posteriores.
Resumen
Las subtags probables completan identificadores de configuración regional parciales añadiendo el sistema de escritura y la región más comunes para un idioma determinado. El método Intl.Locale.maximize() implementa el algoritmo Add Likely Subtags de Unicode para realizar esta expansión.
Puntos clave:
- Las subtags probables se basan en datos de uso lingüístico real
- El método
maximize()añade códigos de sistema de escritura y región faltantes - Las etiquetas de extensión para calendarios y sistemas de numeración permanecen sin cambios
- Utiliza la maximización para normalizar la entrada del usuario y comparar configuraciones regionales
- Las API de formato no requieren configuraciones regionales maximizadas
El método maximize() proporciona una forma estandarizada de trabajar con identificadores de configuración regional completos cuando la lógica de tu aplicación requiere información explícita de sistema de escritura y región.