Comment normaliser les identifiants de locale sous forme standard
Convertir les identifiants de locale au format canonique avec la casse et l'ordre des composants corrects
Introduction
Les identifiants de locale peuvent être écrits de nombreuses façons différentes tout en faisant référence à la même langue et région. Un utilisateur pourrait écrire EN-us, en-US, ou en-us, et les trois représentent l'anglais américain. Lors du stockage, de la comparaison ou de l'affichage des identifiants de locale, ces variations créent des incohérences.
La normalisation convertit les identifiants de locale en une forme canonique standard. Ce processus ajuste la casse des composants, ordonne les mots-clés d'extension par ordre alphabétique et produit une représentation cohérente sur laquelle vous pouvez vous appuyer dans toute votre application.
JavaScript fournit des méthodes intégrées pour normaliser automatiquement les identifiants de locale. Ce guide explique ce que signifie la normalisation, comment l'appliquer dans votre code et quand les identifiants normalisés améliorent votre logique d'internationalisation.
Ce que signifie la normalisation pour les identifiants de locale
La normalisation transforme un identifiant de locale en sa forme canonique selon la norme BCP 47 et les spécifications Unicode. La forme canonique suit des règles spécifiques pour la casse, l'ordre et la structure.
Un identifiant de locale normalisé suit ces conventions :
- Les codes de langue sont en minuscules
- Les codes d'écriture sont en casse de titre avec la première lettre en majuscule
- Les codes de région sont en majuscules
- Les codes de variante sont en minuscules
- Les mots-clés d'extension sont triés par ordre alphabétique
- Les attributs d'extension sont triés par ordre alphabétique
Ces règles créent une représentation standard unique pour chaque locale. Quelle que soit la façon dont un utilisateur écrit un identifiant de locale, la forme normalisée est toujours la même.
Comprendre les règles de normalisation
Chaque composant d'un identifiant de locale a une convention de casse spécifique dans la forme canonique.
Casse des langues
Les codes de langue utilisent toujours des lettres minuscules :
en (correct)
EN (incorrect, but normalizes to en)
eN (incorrect, but normalizes to en)
Cela s'applique aux codes de langue à deux lettres comme à trois lettres.
Casse des scripts
Les codes de script utilisent la casse titre, où la première lettre est en majuscule et les trois lettres restantes sont en minuscules :
Hans (correct)
hans (incorrect, but normalizes to Hans)
HANS (incorrect, but normalizes to Hans)
Les codes de script courants incluent Latn pour le latin, Cyrl pour le cyrillique, Hans pour les caractères han simplifiés et Hant pour les caractères han traditionnels.
Casse des régions
Les codes de région utilisent toujours des lettres majuscules :
US (correct)
us (incorrect, but normalizes to US)
Us (incorrect, but normalizes to US)
Cela s'applique aux codes pays à deux lettres utilisés dans la plupart des identifiants de locale.
Ordre des extensions
Les balises d'extension Unicode contiennent des mots-clés qui spécifient les préférences de formatage. Dans la forme canonique, ces mots-clés apparaissent par ordre alphabétique selon leur clé :
en-US-u-ca-gregory-nu-latn (correct)
en-US-u-nu-latn-ca-gregory (incorrect, but normalizes to first form)
La clé de calendrier ca vient avant la clé de système de numération nu par ordre alphabétique, donc ca-gregory apparaît en premier dans la forme normalisée.
Utiliser Intl.getCanonicalLocales pour normaliser
La méthode Intl.getCanonicalLocales() normalise les identifiants de locale et les renvoie sous forme canonique. C'est la méthode principale de normalisation en JavaScript.
const normalized = Intl.getCanonicalLocales("EN-us");
console.log(normalized);
// ["en-US"]
La méthode accepte un identifiant de locale avec n'importe quelle casse et renvoie la forme canonique correctement formatée.
Normaliser les codes de langue
La méthode convertit les codes de langue en minuscules :
const result = Intl.getCanonicalLocales("FR-fr");
console.log(result);
// ["fr-FR"]
Le code de langue FR devient fr dans la sortie.
Normaliser les codes de script
La méthode convertit les codes de script en casse de titre :
const result = Intl.getCanonicalLocales("zh-HANS-cn");
console.log(result);
// ["zh-Hans-CN"]
Le code de script HANS devient Hans, et le code de région cn devient CN.
Normalisation des codes de région
La méthode convertit les codes de région en majuscules :
const result = Intl.getCanonicalLocales("en-gb");
console.log(result);
// ["en-GB"]
Le code de région gb devient GB dans la sortie.
Normalisation des mots-clés d'extension
La méthode trie les mots-clés d'extension par ordre alphabétique :
const result = Intl.getCanonicalLocales("en-US-u-nu-latn-hc-h12-ca-gregory");
console.log(result);
// ["en-US-u-ca-gregory-hc-h12-nu-latn"]
Les mots-clés se réorganisent de nu-latn-hc-h12-ca-gregory à ca-gregory-hc-h12-nu-latn car ca vient avant hc et hc vient avant nu par ordre alphabétique.
Normalisation de plusieurs identifiants de locale
La méthode Intl.getCanonicalLocales() accepte un tableau d'identifiants de locale et les normalise tous :
const locales = ["EN-us", "fr-FR", "ZH-hans-cn"];
const normalized = Intl.getCanonicalLocales(locales);
console.log(normalized);
// ["en-US", "fr-FR", "zh-Hans-CN"]
Chaque locale du tableau est convertie en sa forme canonique.
Suppression des doublons
La méthode supprime les identifiants de locale en double après normalisation. Si plusieurs valeurs d'entrée se normalisent vers la même forme canonique, le résultat ne contient qu'une seule copie :
const locales = ["en-US", "EN-us", "en-us"];
const normalized = Intl.getCanonicalLocales(locales);
console.log(normalized);
// ["en-US"]
Les trois entrées représentent la même locale, donc la sortie contient un seul identifiant normalisé.
Cette déduplication est utile lors du traitement des entrées utilisateur ou de la fusion de listes de locales provenant de plusieurs sources.
Gestion des identifiants invalides
Si un identifiant de locale du tableau est invalide, la méthode lève une RangeError :
try {
Intl.getCanonicalLocales(["en-US", "invalid", "fr-FR"]);
} catch (error) {
console.error(error.message);
// "invalid is not a structurally valid language tag"
}
Lors de la normalisation de listes fournies par l'utilisateur, validez ou interceptez les erreurs pour chaque locale individuellement afin d'identifier quels identifiants spécifiques sont invalides.
Utilisation d'Intl.Locale pour la normalisation
Le constructeur Intl.Locale normalise également les identifiants de locale lors de la création d'objets locale. Vous pouvez accéder à la forme normalisée via la méthode toString().
const locale = new Intl.Locale("EN-us");
console.log(locale.toString());
// "en-US"
Le constructeur accepte toute casse valide et produit un objet locale normalisé.
Accès aux composants normalisés
Chaque propriété de l'objet locale renvoie la forme normalisée de ce composant :
const locale = new Intl.Locale("ZH-hans-CN");
console.log(locale.language);
// "zh"
console.log(locale.script);
// "Hans"
console.log(locale.region);
// "CN"
console.log(locale.baseName);
// "zh-Hans-CN"
Les propriétés language, script et region utilisent toutes la casse correcte pour la forme canonique.
Normalisation avec options
Lorsque vous créez un objet locale avec des options, le constructeur normalise à la fois l'identifiant de base et les options :
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"
Les mots-clés d'extension apparaissent dans l'ordre alphabétique dans la sortie, même si l'objet options ne spécifie aucun ordre particulier.
Pourquoi la normalisation est importante
La normalisation assure la cohérence dans votre application. Lorsque vous stockez, affichez ou comparez des identifiants de locale, l'utilisation de la forme canonique prévient les bugs subtils et améliore la fiabilité.
Stockage cohérent
Lors du stockage d'identifiants de locale dans des bases de données, des fichiers de configuration ou un stockage local, les formes normalisées empêchent la duplication :
const userPreferences = new Set();
function saveUserLocale(identifier) {
const normalized = Intl.getCanonicalLocales(identifier)[0];
userPreferences.add(normalized);
}
saveUserLocale("en-US");
saveUserLocale("EN-us");
saveUserLocale("en-us");
console.log(userPreferences);
// Set { "en-US" }
Sans normalisation, l'ensemble contiendrait trois entrées pour la même locale. Avec la normalisation, il contient correctement une seule entrée.
Comparaison fiable
La comparaison d'identifiants de locale nécessite une normalisation. Deux identifiants qui diffèrent uniquement par la casse représentent la même locale :
function isSameLocale(locale1, locale2) {
const normalized1 = Intl.getCanonicalLocales(locale1)[0];
const normalized2 = Intl.getCanonicalLocales(locale2)[0];
return normalized1 === normalized2;
}
console.log(isSameLocale("en-US", "EN-us"));
// true
console.log(isSameLocale("en-US", "en-GB"));
// false
La comparaison directe de chaînes d'identifiants non normalisés produit des résultats incorrects.
Affichage cohérent
Lors de l'affichage d'identifiants de locale aux utilisateurs ou dans une sortie de débogage, les formes normalisées fournissent un formatage cohérent :
function displayLocale(identifier) {
try {
const normalized = Intl.getCanonicalLocales(identifier)[0];
return `Current locale: ${normalized}`;
} catch (error) {
return "Invalid locale identifier";
}
}
console.log(displayLocale("EN-us"));
// "Current locale: en-US"
console.log(displayLocale("zh-HANS-cn"));
// "Current locale: zh-Hans-CN"
Les utilisateurs voient des identifiants de locale correctement formatés quel que soit le format d'entrée.
Applications pratiques
La normalisation résout les problèmes courants lors de la manipulation d'identifiants de locale dans des applications réelles.
Normalisation des entrées utilisateur
Lorsque les utilisateurs saisissent des identifiants de locale dans des formulaires ou des paramètres, normalisez l'entrée avant de la stocker :
function processLocaleInput(input) {
try {
const normalized = Intl.getCanonicalLocales(input)[0];
return {
success: true,
locale: normalized
};
} catch (error) {
return {
success: false,
error: "Please enter a valid locale identifier"
};
}
}
const result = processLocaleInput("fr-ca");
console.log(result);
// { success: true, locale: "fr-CA" }
Cela garantit un formatage cohérent dans votre base de données ou configuration.
Construction de tables de correspondance de locales
Lors de la création de tables de correspondance pour les traductions ou les données spécifiques à une locale, utilisez des clés normalisées :
const translations = new Map();
function addTranslation(locale, key, value) {
const normalized = Intl.getCanonicalLocales(locale)[0];
if (!translations.has(normalized)) {
translations.set(normalized, {});
}
translations.get(normalized)[key] = value;
}
addTranslation("en-us", "hello", "Hello");
addTranslation("EN-US", "goodbye", "Goodbye");
console.log(translations.get("en-US"));
// { hello: "Hello", goodbye: "Goodbye" }
Les deux appels à addTranslation utilisent la même clé normalisée, donc les traductions sont stockées dans le même objet.
Fusion de listes de locales
Lors de la combinaison d'identifiants de locale provenant de plusieurs sources, normalisez-les et supprimez les doublons :
function mergeLocales(...sources) {
const allLocales = sources.flat();
const normalized = Intl.getCanonicalLocales(allLocales);
return normalized;
}
const userLocales = ["en-us", "fr-FR"];
const appLocales = ["EN-US", "de-de"];
const systemLocales = ["en-US", "es-mx"];
const merged = mergeLocales(userLocales, appLocales, systemLocales);
console.log(merged);
// ["en-US", "fr-FR", "de-DE", "es-MX"]
La méthode supprime les doublons et normalise la casse dans toutes les sources.
Création d'interfaces de sélection de locale
Lors de la construction de menus déroulants ou d'interfaces de sélection, normalisez les identifiants de locale pour l'affichage :
function buildLocaleOptions(locales) {
const normalized = Intl.getCanonicalLocales(locales);
return normalized.map(locale => {
const localeObj = new Intl.Locale(locale);
const displayNames = new Intl.DisplayNames([locale], {
type: "language"
});
return {
value: locale,
label: displayNames.of(localeObj.language)
};
});
}
const options = buildLocaleOptions(["EN-us", "fr-FR", "DE-de"]);
console.log(options);
// [
// { value: "en-US", label: "English" },
// { value: "fr-FR", label: "French" },
// { value: "de-DE", label: "German" }
// ]
Les valeurs normalisées fournissent des identifiants cohérents pour les soumissions de formulaires.
Validation des fichiers de configuration
Lors du chargement d'identifiants de locale depuis des fichiers de configuration, normalisez-les pendant l'initialisation :
function loadLocaleConfig(config) {
const validatedConfig = {
defaultLocale: null,
supportedLocales: []
};
try {
validatedConfig.defaultLocale = Intl.getCanonicalLocales(
config.defaultLocale
)[0];
} catch (error) {
console.error("Invalid default locale:", config.defaultLocale);
validatedConfig.defaultLocale = "en-US";
}
config.supportedLocales.forEach(locale => {
try {
const normalized = Intl.getCanonicalLocales(locale)[0];
validatedConfig.supportedLocales.push(normalized);
} catch (error) {
console.warn("Skipping invalid locale:", locale);
}
});
return validatedConfig;
}
const config = {
defaultLocale: "en-us",
supportedLocales: ["EN-us", "fr-FR", "invalid", "de-DE"]
};
const validated = loadLocaleConfig(config);
console.log(validated);
// {
// defaultLocale: "en-US",
// supportedLocales: ["en-US", "fr-FR", "de-DE"]
// }
Cela détecte les erreurs de configuration en amont et garantit que votre application utilise des identifiants normalisés valides.
Normalisation et correspondance de locales
La normalisation est importante pour les algorithmes de correspondance de locales. Lors de la recherche de la meilleure correspondance de locale pour une préférence utilisateur, comparez les formes normalisées :
{/* CODE_PLACEHOLDER_87bb89051dc667cf8907562ebdf4995f */
La normalisation garantit que la logique de correspondance fonctionne correctement quelle que soit la casse de l'entrée.
La normalisation ne modifie pas la signification
La normalisation affecte uniquement la représentation d'un identifiant de locale. Elle ne modifie pas la langue, l'écriture ou la région que l'identifiant représente.
const locale1 = new Intl.Locale("en-us");
const locale2 = new Intl.Locale("EN-US");
console.log(locale1.language === locale2.language);
// true
console.log(locale1.region === locale2.region);
// true
console.log(locale1.toString() === locale2.toString());
// true
Les deux identifiants font référence à l'anglais américain. La normalisation garantit simplement qu'ils sont écrits de la même manière.
Cela diffère des opérations telles que maximize() et minimize(), qui ajoutent ou suppriment des composants et peuvent modifier la spécificité de l'identifiant.
Prise en charge des navigateurs
La méthode Intl.getCanonicalLocales() fonctionne dans tous les navigateurs modernes. Chrome, Firefox, Safari et Edge offrent une prise en charge complète.
Node.js prend en charge Intl.getCanonicalLocales() à partir de la version 9, avec une prise en charge complète dans la version 10 et les versions ultérieures.
Le constructeur Intl.Locale et son comportement de normalisation fonctionnent dans tous les navigateurs qui prennent en charge l'API Intl.Locale. Cela inclut les versions modernes de Chrome, Firefox, Safari et Edge.
Résumé
La normalisation convertit les identifiants de locale en leur forme canonique en appliquant des règles de casse standard et en triant les mots-clés d'extension. Cela crée des représentations cohérentes que vous pouvez stocker, comparer et afficher de manière fiable.
Concepts clés :
- La forme canonique utilise des minuscules pour les langues, une casse de titre pour les écritures et des majuscules pour les régions
- Les mots-clés d'extension sont triés par ordre alphabétique dans la forme canonique
- La méthode
Intl.getCanonicalLocales()normalise les identifiants et supprime les doublons - Le constructeur
Intl.Localeproduit également une sortie normalisée - La normalisation ne modifie pas la signification d'un identifiant de locale
- Utilisez des identifiants normalisés pour le stockage, la comparaison et l'affichage
La normalisation est une opération fondamentale pour toute application qui travaille avec des identifiants de locale. Elle prévient les bugs causés par une casse incohérente et garantit que votre logique d'internationalisation gère les identifiants de locale de manière fiable.