Locale est une classe Foundation dans iOS et macOS qui encapsule les conventions linguistiques et culturelles de l'utilisateur : format des dates, des nombres, des devises et des unités de mesure. Selon Apple Developer Documentation, 2024, Locale détermine comment DateFormatter affiche un mois (janvier ou January), le séparateur décimal d'un nombre (virgule ou point) et le symbole de devise (rouble, dollar ou euro). Chaque instance de Locale est liée à un identifiant comme ru_RU ou en_US, où la première partie est le code de langue (ISO 639-1) et la seconde le code de région (ISO 3166-1). Contrairement à TimeZone, Locale n'affecte pas la valeur absolue du temps, seulement sa représentation textuelle.
Points clés
Locale est un type valeur en Swift (NSLocale en Objective-C) représentant un ensemble de règles de formatage spécifiques à une langue et une région données. Contrairement à TimeZone, qui détermine le décalage absolu du temps, Locale détermine comment le temps, les nombres et la devise apparaissent dans la représentation textuelle. La même date 2024-07-21 sera affichée comme « 21 juillet 2024 » pour ru_RU et « July 21, 2024 » pour en_US.
Chaque instance Locale comprend deux composants : Langue (détermine les noms des mois, des jours de la semaine, l'ordre des mots) et Région (détermine le format numérique, la devise, le calendrier). La combinaison de ces composants est codée dans un identifiant selon la norme BCP 47 : ru_RU (russe, Russie), en_US (anglais, États-Unis), de_DE (allemand, Allemagne).
Selon Unicode CLDR (2024), le nombre de paramètres régionaux pris en charge dans iOS dépasse 700 combinaisons langue-région. Foundation utilise les données du CLDR (Common Locale Data Repository) — le référentiel le plus complet de données de localisation maintenu par le Consortium Unicode. Cela garantit un formatage cohérent sur tous les appareils Apple.
DateFormatter utilise Locale pour sélectionner les noms corrects des mois et des jours, déterminer l'ordre des composants de la date (jour/mois/année ou mois/jour/année) et les séparateurs. Sans spécifier explicitement Locale, DateFormatter utilise la locale de l'appareil — c'est correct pour l'interface utilisateur mais dangereux pour les données serveur où le format doit être fixe.
| Composant | ru_RU | en_US | de_DE |
|---|---|---|---|
| Date (medium) | 21 juillet 2024 | Jul 21, 2024 | 21.07.2024 |
| Nombre (1000.5) | 1 000,5 | 1,000.5 | 1.000,5 |
| Devise (100) | 100,00 ₽ | $100.00 | 100,00 € |
| Calendrier | Grégorien | Grégorien | Grégorien |
| Séparateur de liste | ; | , | ; |
NumberFormatter utilise Locale pour déterminer le séparateur décimal (virgule ou point), le séparateur de groupement (espace, virgule, point) et le symbole de devise. Ignorer Locale lors de l'analyse des nombres est l'une des causes courantes de bugs dans les applications internationales : le nombre « 1,5 » signifie « un et demi » pour ru_RU, mais pour en_US l'analyseur numérique le lira comme « cinq » après la virgule.
Important : Calendar créé via Calendar.current hérite de la locale de l'appareil. Calendar(identifier: .gregorian) avec une locale explicitement définie est l'approche recommandée pour un formatage prévisible. Lorsque vous travaillez avec des dates ISO 8601, utilisez toujours Locale(identifier: « en_US_POSIX ») — une locale spéciale pour le formatage technique qui n'est pas affectée par les paramètres régionaux.
L'identifiant Locale se compose d'un code de langue (ISO 639-1, deux caractères) et d'un code de région (ISO 3166-1, deux caractères), séparés par un tiret bas. Exemples : ru_RU, en_US, fr_FR, zh_Hans_CN (chinois, écriture simplifiée, Chine). Foundation prend également en charge les identifiants au format BCP 47 : ru-RU, en-US, utilisés dans les normes Web.
Outre les identifiants complets, Locale peut être créé uniquement par langue : Locale(identifier: « ru ») renvoie une locale avec la langue russe et la région par défaut pour cette langue (généralement la Russie). De même pour l'anglais : Locale(identifier: « en ») utilise la région des États-Unis. Cette approche est utile pour définir la langue de formatage sans être lié à une région spécifique.
Paramètres régionaux spéciaux incluent en_US_POSIX — une locale technique pour le formatage automatique des dates et des nombres, garantissant un format stable indépendamment des paramètres utilisateur. Cette locale est obligatoire pour analyser les dates des API serveur, en particulier pour le format ISO 8601. Elle utilise le calendrier grégorien, le format 24 heures et le point comme séparateur décimal.
import Foundation
// Identifiants de paramètres régionaux disponibles
let available: [String] = Locale.availableIdentifiers
print("Total des paramètres régionaux : \(available.count)")
// Filtrer les paramètres régionaux russes
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("Paramètres régionaux russes : \(russianLocales)")
// Composants de paramètres régionaux
let locale = Locale(identifier: "de_DE")
print("Langue : \(locale.languageCode ?? "nil")")
print("Région : \(locale.regionCode ?? "nil")")
print("Devise : \(locale.currencyCode ?? "nil")")
print("Calendrier : \(locale.calendar.identifier)")
Vérifier les paramètres régionaux disponibles via Locale.availableIdentifiers renvoie un tableau de tous les identifiants pris en charge par la version actuelle d'iOS. Pour filtrer par région, utilisez Locale.availableIdentifiers.filter avec la vérification de regionCode. Ceci est utile pour construire une interface de sélection de région sans liste codée en dur.
Locale.current est le moyen principal d'obtenir la locale actuelle de l'appareil définie par l'utilisateur dans les paramètres iOS (Settings > General > Language & Region). Cette propriété se met à jour automatiquement lors du changement de langue ou de région dans les paramètres sans redémarrer l'application. Cependant, elle peut ne pas correspondre à la locale préférée pour l'affichage du contenu : un utilisateur peut définir la langue de l'interface sur anglais mais visualiser les dates au format russe.
Pour une détermination plus précise des préférences de l'utilisateur, utilisez Locale.preferredLanguages — un tableau de langues classées par priorité utilisateur. Le premier élément est la langue principale de l'interface. Cette liste correspond aux paramètres dans Language & Region, y compris le glissement des langues dans l'ordre de préférence. Les applications de communication (messageries, clients email) doivent tenir compte de cet ordre lors du choix de la langue d'affichage du contenu.
import Foundation
// Paramètres régionaux système actuels
let current = Locale.current
print("Paramètres régionaux actuels : \(current.identifier)")
print("Langue : \(current.language?.disjointName ?? "nil")")
// Langues préférées de l'utilisateur
let preferred = Locale.preferredLanguages
print("Langues préférées : \(preferred)")
// Obtenir la région des paramètres régionaux actuels
if let region = current.regionCode {
let regionLocale = Locale(identifier: "en_\(region)")
let countryName = regionLocale.localizedString(
forRegionCode: region
)
print("Pays : \(countryName ?? region)")
}
// Vérifier le format 24h
let uses24h = current.uses24hClock(
for: .dateAndTime
)
print("Utilise 24h : \(uses24h)")
Localisation dans l'interface utilisateur : pour afficher les noms des mois et des jours dans la langue de l'interface, utilisez Calendar avec une locale définie. Calendar.current.symbols(for: .month) renvoie les noms des mois dans la langue de la locale actuelle. Pour afficher les noms des pays dans la langue de l'utilisateur, utilisez Locale.current.localizedString(forRegionCode:).
Formatage de date avec prise en compte de la locale est une tâche clé lors de l'affichage des dates à l'utilisateur. DateFormatter avec une locale définie sélectionne automatiquement le format de date et d'heure correct pour la région de l'utilisateur. Pour dateStyle et timeStyle avec les valeurs .short, .medium, .long, .full, le formateur utilise les règles de la locale pour composer les composants de la date.
import Foundation
let date = Date()
// Formatage avec différents paramètres régionaux
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.locale = Locale(identifier: "ru_RU")
print("Russe : \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "en_US")
print("Anglais : \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "ja_JP")
print("Japonais : \(formatter.string(from: date))")
// Formatage de devise avec paramètres régionaux
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency
numFormatter.locale = Locale(identifier: "de_DE")
print("Devise allemande : \(numFormatter.string(from: 1234.56) ?? "nil")")
numFormatter.locale = Locale(identifier: "en_US")
print("Devise américaine : \(numFormatter.string(from: 1234.56) ?? "nil")")
Analyse des dates des API serveur doit toujours utiliser Locale(identifier: « en_US_POSIX ») pour un format fixe. Les serveurs envoient généralement les dates au format ISO 8601 avec des noms de mois en anglais, et l'utilisation de la locale actuelle de l'appareil peut entraîner des erreurs d'analyse si l'utilisateur se trouve dans une région non anglophone. en_US_POSIX garantit que l'analyse ne dépend pas des paramètres de l'appareil.
import Foundation
// Analyse correcte de date serveur
let isoFormatter = DateFormatter()
isoFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
isoFormatter.locale = Locale(identifier: "en_US_POSIX")
isoFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let serverDate = "2024-07-21T14:30:00+0000"
if let parsed = isoFormatter.date(from: serverDate) {
print("Date analysée : \(parsed)")
}
// Nom de devise localisé
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
forCurrencyCode: "RUB"
)
print("Rouble russe dans les paramètres régionaux américains : \(currencyName ?? "nil")")
Capacités supplémentaires : Locale fournit des descriptions localisées de ses composants via les méthodes localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:) et localizedString(forCalendarIdentifier:). Ces méthodes renvoient les noms dans la langue de la locale sur laquelle elles sont appelées. Par exemple, Locale(identifier: « ru_RU »).localizedString(forCountryCode: « DE ») renvoie « Allemagne ».
Ignorer Locale lors de l'analyse des nombres est une erreur critique dans les applications internationales. NumberFormatter sans locale explicite utilise la locale actuelle de l'appareil. Si un utilisateur en Russie saisit « 1,5 », NumberFormatter.number(from: « 1,5 ») renvoie correctement 1.5. Mais si le même code s'exécute sur un appareil avec la locale en_US, l'analyse renvoie nil car pour en_US le séparateur décimal est un point.
Absence d'en_US_POSIX pour les dates serveur conduit à des bugs subtils. DateFormatter avec dateFormat et locale = Locale.current peut échouer pour les utilisateurs de régions où le format de date diffère du format américain. Par exemple, en Allemagne, DateFormatter peut s'attendre à « 21.07.2024 » tandis que le serveur envoie « 07/21/2024 ». en_US_POSIX garantit un format fixe pour l'analyse automatique indépendamment de la région de l'utilisateur.
Comparer des chaînes de date au lieu d'utiliser Date est une autre erreur courante. Les développeurs comparent parfois des représentations textuelles de dates de différentes locales, obtenant des résultats incorrects. Locale ne change que l'affichage, pas la valeur absolue de la date. Comparez toujours des objets Date, pas leurs représentations textuelles. Pour comparer des composants de date, utilisez Calendar avec une locale explicitement définie.
Selon WWDC 2023, environ 30 % des problèmes d'internationalisation dans les applications sont liés à une configuration incorrecte de Locale. Apple recommande de toujours définir explicitement la locale pour DateFormatter et NumberFormatter lors du travail avec des données serveur et d'utiliser Locale.current uniquement pour l'affichage dans l'interface utilisateur. Cette pratique simple élimine la plupart des bugs liés aux paramètres régionaux.
Foire aux questions
Locale est une classe Foundation représentant les règles culturelles et linguistiques de formatage : format de date, de nombre, de devise et d'unités de mesure. Elle est utilisée conjointement avec DateFormatter, NumberFormatter et Calendar pour l'affichage localisé des données.
Locale détermine le format d'affichage (langue, conventions régionales), tandis que TimeZone détermine le décalage absolu du temps par rapport à UTC. Locale affecte la représentation textuelle, TimeZone affecte la valeur numérique du temps. Les deux sont utilisés ensemble pour un formatage complet de la date.
en_US_POSIX est une locale spéciale pour le formatage technique garantissant un format stable indépendamment des paramètres utilisateur. Il est obligatoire pour analyser les dates serveur (ISO 8601) et travailler avec des API où le format doit être prévisible.
Locale.availableIdentifiers renvoie un tableau de chaînes avec les identifiants de tous les paramètres régionaux pris en charge. Pour filtrer par langue, utilisez filter avec hasPrefix ; pour obtenir la région, utilisez Locale(identifier:).regionCode.
NumberFormatter utilise Locale pour déterminer le séparateur décimal (virgule ou point), le symbole de devise et le séparateur de groupement. Pour un format fixe, définissez la locale sur en_US_POSIX ou définissez explicitement les propriétés du formateur.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi