Locale ist eine Foundation-Klasse in iOS und macOS, die die sprachlichen und kulturellen Konventionen des Benutzers kapselt: Datumsformat, Zahlenformat, Währungen und Maßeinheiten. Laut Apple Developer Documentation, 2024 bestimmt Locale, wie DateFormatter einen Monat anzeigt (Januar oder January), das Dezimaltrennzeichen in einer Zahl (Komma oder Punkt) und das Währungssymbol (Rubel, Dollar oder Euro). Jede Locale-Instanz ist mit einer Kennung wie ru_RU oder en_US verknüpft, wobei der erste Teil der Sprachcode (ISO 639-1) und der zweite der Regionscode (ISO 3166-1) ist. Anders als TimeZone beeinflusst Locale nicht den absoluten Zeitwert, sondern nur seine Zeichenfolgendarstellung.
Wichtige Punkte
Locale ist ein Werttyp in Swift (NSLocale in Objective-C), der eine Reihe von Formatierungsregeln darstellt, die für eine bestimmte Sprache und Region spezifisch sind. Anders als TimeZone, das den absoluten Zeitversatz bestimmt, legt Locale fest, wie Zeit, Zahlen und Währung in der Zeichenfolgendarstellung aussehen. Dasselbe Datum 2024-07-21 wird für ru_RU als „21. Juli 2024“ und für en_US als „July 21, 2024“ angezeigt.
Jede Locale-Instanz besteht aus zwei Komponenten: Sprache (bestimmt Monatsnamen, Wochentagsnamen, Wortreihenfolge) und Region (bestimmt Zahlenformat, Währung, Kalender). Die Kombination dieser Komponenten wird nach dem BCP-47-Standard in einer Kennung codiert: ru_RU (Russisch, Russland), en_US (Englisch, USA), de_DE (Deutsch, Deutschland).
Laut Unicode CLDR (2024) übersteigt die Anzahl der unterstützten Gebietsschemata in iOS 700 Sprach-Region-Kombinationen. Foundation verwendet Daten aus dem CLDR (Common Locale Data Repository) — dem umfassendsten Repository für Lokalisierungsdaten, das vom Unicode Consortium verwaltet wird. Dies gewährleistet eine konsistente Formatierung auf allen Apple-Geräten.
DateFormatter verwendet Locale, um die korrekten Monats- und Tagesnamen auszuwählen, die Reihenfolge der Datumskomponenten (Tag/Monat/Jahr oder Monat/Tag/Jahr) und Trennzeichen zu bestimmen. Ohne explizite Angabe von Locale verwendet DateFormatter das Gerätegebietsschema — dies ist für die Benutzeroberfläche korrekt, aber gefährlich für Serverdaten, bei denen das Format fest sein sollte.
| Komponente | ru_RU | en_US | de_DE |
|---|---|---|---|
| Datum (medium) | 21. Juli 2024 | Jul 21, 2024 | 21.07.2024 |
| Zahl (1000.5) | 1 000,5 | 1,000.5 | 1.000,5 |
| Währung (100) | 100,00 ₽ | $100.00 | 100,00 € |
| Kalender | Gregorianisch | Gregorianisch | Gregorianisch |
| Listentrennzeichen | ; | , | ; |
NumberFormatter verwendet Locale, um das Dezimaltrennzeichen (Komma oder Punkt), das Gruppierungstrennzeichen (Leerzeichen, Komma, Punkt) und das Währungssymbol zu bestimmen. Das Ignorieren von Locale beim Parsen von Zahlen ist eine der häufigsten Ursachen für Fehler in internationalen Anwendungen: Die Zahl „1,5“ bedeutet für ru_RU „eineinhalb“, aber für en_US liest der digitale Parser sie als „fünf“ nach dem Komma.
Wichtig: Ein über Calendar.current erstellter Calendar erbt das Gerätegebietsschema. Calendar(identifier: .gregorian) mit explizit festgelegtem Gebietsschema ist der empfohlene Ansatz für vorhersagbare Formatierung. Verwenden Sie bei der Arbeit mit ISO-8601-Daten immer Locale(identifier: „en_US_POSIX“) — ein spezielles Gebietsschema für technische Formatierung, das nicht von regionalen Einstellungen beeinflusst wird.
Die Locale-Kennung besteht aus einem Sprachcode (ISO 639-1, zwei Zeichen) und einem Regionscode (ISO 3166-1, zwei Zeichen), getrennt durch einen Unterstrich. Beispiele: ru_RU, en_US, fr_FR, zh_Hans_CN (Chinesisch, vereinfachte Schrift, China). Foundation unterstützt auch Kennungen im BCP-47-Format: ru-RU, en-US, die in Webstandards verwendet werden.
Neben vollständigen Kennungen kann Locale auch nur nach Sprache erstellt werden: Locale(identifier: “ru“) gibt ein Gebietsschema mit der russischen Sprache und der Standardregion für diese Sprache (normalerweise Russland) zurück. Ähnlich für Englisch: Locale(identifier: “en“) verwendet die US-Region. Dieser Ansatz ist nützlich, um die Formatierungssprache festzulegen, ohne an eine bestimmte Region gebunden zu sein.
Spezielle Gebietsschemata umfassen en_US_POSIX — ein technisches Gebietsschema für die maschinelle Formatierung von Daten und Zahlen, das ein stabiles Format unabhängig von Benutzereinstellungen gewährleistet. Dieses Gebietsschema ist für das Parsen von Daten aus Server-APIs obligatorisch, insbesondere für das ISO-8601-Format. Es verwendet den gregorianischen Kalender, das 24-Stunden-Zeitformat und den Punkt als Dezimaltrennzeichen.
import Foundation
// Verfügbare Gebietsschema-Kennungen
let available: [String] = Locale.availableIdentifiers
print("Gebietsschema insgesamt: \(available.count)")
// Russische Gebietsschemata filtern
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("Russische Gebietsschemata: \(russianLocales)")
// Gebietsschema-Komponenten
let locale = Locale(identifier: "de_DE")
print("Sprache: \(locale.languageCode ?? "nil")")
print("Region: \(locale.regionCode ?? "nil")")
print("Währung: \(locale.currencyCode ?? "nil")")
print("Kalender: \(locale.calendar.identifier)")
Verfügbare Gebietsschemata prüfen über Locale.availableIdentifiers gibt ein Array aller von der aktuellen iOS-Version unterstützten Kennungen zurück. Zum Filtern nach Region verwenden Sie Locale.availableIdentifiers.filter mit einer regionCode-Prüfung. Dies ist nützlich, um eine Regionsauswahl-Benutzeroberfläche ohne hartcodierte Liste zu erstellen.
Locale.current ist die primäre Methode, um das aktuelle Gerätegebietsschema zu erhalten, das vom Benutzer in den iOS-Einstellungen (Settings > General > Language & Region) festgelegt wurde. Diese Eigenschaft wird automatisch aktualisiert, wenn die Sprache oder Region in den Einstellungen geändert wird, ohne dass die Anwendung neu gestartet werden muss. Sie kann jedoch von dem für die Inhaltsanzeige bevorzugten Gebietsschema abweichen: Ein Benutzer kann die Oberflächensprache auf Englisch setzen, aber Daten im russischen Format anzeigen.
Für eine genauere Bestimmung der Benutzerpräferenzen verwenden Sie Locale.preferredLanguages — ein Array von Sprachen, geordnet nach Benutzerpriorität. Das erste Element ist die primäre Oberflächensprache. Diese Liste entspricht den Einstellungen unter Language & Region, einschließlich des Ziehens von Sprachen in der Reihenfolge der Präferenz. Kommunikations-Apps (Messenger, E-Mail-Clients) sollten diese Reihenfolge bei der Auswahl der Anzeigesprache für Inhalte berücksichtigen.
import Foundation
// Aktuelles Systemgebietsschema
let current = Locale.current
print("Aktuelles Gebietsschema: \(current.identifier)")
print("Sprache: \(current.language?.disjointName ?? "nil")")
// Bevorzugte Sprachen des Benutzers
let preferred = Locale.preferredLanguages
print("Bevorzugte Sprachen: \(preferred)")
// Region aus aktuellem Gebietsschema abrufen
if let region = current.regionCode {
let regionLocale = Locale(identifier: "en_\(region)")
let countryName = regionLocale.localizedString(
forRegionCode: region
)
print("Land: \(countryName ?? region)")
}
// 24h-Format prüfen
let uses24h = current.uses24hClock(
for: .dateAndTime
)
print("Verwendet 24h: \(uses24h)")
Lokalisierung in der Benutzeroberfläche: Zur Anzeige von Monats- und Tagesnamen in der Oberflächensprache verwenden Sie Calendar mit einem festgelegten Gebietsschema. Calendar.current.symbols(for: .month) gibt die Monatsnamen in der Sprache des aktuellen Gebietsschemas zurück. Zur Anzeige von Ländernamen in der Benutzersprache verwenden Sie Locale.current.localizedString(forRegionCode:).
Datumsformatierung mit Gebietsschema-Bewusstsein ist eine Schlüsselaufgabe bei der Anzeige von Daten für den Benutzer. DateFormatter mit einem festgelegten Gebietsschema wählt automatisch das korrekte Datums- und Zeitformat für die Region des Benutzers aus. Für dateStyle und timeStyle mit den Werten .short, .medium, .long, .full verwendet der Formatierer die Gebietsschema-Regeln, um die Datumskomponenten zusammenzusetzen.
import Foundation
let date = Date()
// Formatierung mit verschiedenen Gebietsschemata
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.locale = Locale(identifier: "ru_RU")
print("Russisch: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "en_US")
print("Englisch: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "ja_JP")
print("Japanisch: \(formatter.string(from: date))")
// Währungsformatierung mit Gebietsschema
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency
numFormatter.locale = Locale(identifier: "de_DE")
print("Deutsche Währung: \(numFormatter.string(from: 1234.56) ?? "nil")")
numFormatter.locale = Locale(identifier: "en_US")
print("US-Währung: \(numFormatter.string(from: 1234.56) ?? "nil")")
Parsen von Daten aus Server-APIs sollte für ein festes Format immer Locale(identifier: „en_US_POSIX“) verwenden. Server senden Daten normalerweise im ISO-8601-Format mit englischen Monatsnamen, und die Verwendung des aktuellen Gerätegebietsschemas kann zu Parsing-Fehlern führen, wenn sich der Benutzer in einer nicht-englischen Region befindet. en_US_POSIX stellt sicher, dass das Parsen nicht von Geräteeinstellungen abhängt.
import Foundation
// Korrektes Server-Datumsparsen
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("Geparstes Datum: \(parsed)")
}
// Lokalisierter Währungsname
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
forCurrencyCode: "RUB"
)
print("Russischer Rubel im US-Gebietsschema: \(currencyName ?? "nil")")
Zusätzliche Funktionen: Locale bietet lokalisierte Beschreibungen seiner Komponenten über die Methoden localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:) und localizedString(forCalendarIdentifier:). Diese Methoden geben Namen in der Sprache des Gebietsschemas zurück, in dem sie aufgerufen werden. Beispiel: Locale(identifier: “ru_RU“).localizedString(forCountryCode: “DE“) gibt „Deutschland“ zurück.
Ignorieren von Locale beim Parsen von Zahlen ist ein kritischer Fehler in internationalen Anwendungen. NumberFormatter ohne explizites Gebietsschema verwendet das aktuelle Gerätegebietsschema. Wenn ein Benutzer in Russland „1,5“ eingibt, gibt NumberFormatter.number(from: „1,5“) korrekt 1.5 zurück. Wenn derselbe Code jedoch auf einem Gerät mit en_US-Gebietsschema ausgeführt wird, gibt das Parsen nil zurück, da das Dezimaltrennzeichen für en_US ein Punkt ist.
Fehlendes en_US_POSIX für Serverdaten führt zu subtilen Fehlern. DateFormatter mit dateFormat und locale = Locale.current kann bei Benutzern aus Regionen, in denen das Datumsformat vom amerikanischen abweicht, fehlschlagen. In Deutschland erwartet DateFormatter beispielsweise „21.07.2024“, während der Server „07/21/2024“ sendet. en_US_POSIX gewährleistet ein festes Format für maschinelles Parsen unabhängig von der Region des Benutzers.
Vergleich von Datumszeichenfolgen anstelle der Verwendung von Date ist ein weiterer häufiger Fehler. Entwickler vergleichen manchmal Zeichenfolgendarstellungen von Daten aus verschiedenen Gebietsschemata und erhalten falsche Ergebnisse. Locale ändert nur die Anzeige, nicht den absoluten Datumswert. Vergleichen Sie immer Date-Objekte, nicht ihre Zeichenfolgendarstellungen. Zum Vergleichen von Datumskomponenten verwenden Sie Calendar mit einem explizit festgelegten Gebietsschema.
Laut WWDC 2023 hängen etwa 30% der Internationalisierungsprobleme in Anwendungen mit einer falschen Locale-Konfiguration zusammen. Apple empfiehlt, bei der Arbeit mit Serverdaten immer explizit das Gebietsschema für DateFormatter und NumberFormatter festzulegen und Locale.current nur für die UI-Anzeige zu verwenden. Diese einfache Praxis beseitigt die meisten Fehler im Zusammenhang mit regionalen Einstellungen.
Häufig gestellte Fragen
Locale ist eine Foundation-Klasse, die kulturelle und sprachliche Formatierungsregeln darstellt: Datumsformat, Zahlenformat, Währung und Maßeinheiten. Sie wird zusammen mit DateFormatter, NumberFormatter und Calendar für die lokalisierte Datenanzeige verwendet.
Locale bestimmt das Anzeigeformat (Sprache, regionale Konventionen), während TimeZone den absoluten Zeitversatz relativ zur UTC bestimmt. Locale beeinflusst die Zeichenfolgendarstellung, TimeZone den numerischen Zeitwert. Beide werden zusammen für die vollständige Datumsformatierung verwendet.
en_US_POSIX ist ein spezielles Gebietsschema für technische Formatierung, das ein stabiles Format unabhängig von Benutzereinstellungen gewährleistet. Es ist obligatorisch für das Parsen von Serverdaten (ISO 8601) und die Arbeit mit APIs, bei denen das Format vorhersagbar sein muss.
Locale.availableIdentifiers gibt ein Array von Zeichenfolgen mit Kennungen aller unterstützten Gebietsschemata zurück. Zum Filtern nach Sprache verwenden Sie filter mit hasPrefix; zum Erhalten der Region verwenden Sie Locale(identifier:).regionCode.
NumberFormatter verwendet Locale, um das Dezimaltrennzeichen (Komma oder Punkt), das Währungssymbol und das Gruppierungstrennzeichen zu bestimmen. Für ein festes Format setzen Sie das Gebietsschema auf en_US_POSIX oder legen Sie die Eigenschaften des Formatierers explizit fest.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch