Locale — is een Foundation klasse in iOS en macOS die de taalkundige en culturele conventies van de gebruiker inkapselt: het formaat van datums, getallen, valuta's en meeteenheden. Volgens Apple Developer Documentation, 2024 bepaalt Locale hoe DateFormatter een maand weergeeft (januari of January), de decimale scheiding in een getal (komma of punt) en het valutasymbool (euro, dollar of pond). Elk Locale-exemplaar is gekoppeld aan een identificatie zoals ru_RU of en_US, waarbij het eerste deel de taalcode is (ISO 639-1) en het tweede deel de regiocode (ISO 3166-1). In tegenstelling tot TimeZone beïnvloedt Locale niet de absolute tijdswaarde, alleen de tekstuele weergave ervan.
Belangrijkste punten
Locale — is een value-type in Swift (NSLocale in Objective-C) dat een set opmaakregels vertegenwoordigt die kenmerkend zijn voor een specifieke taal en regio. In tegenstelling tot TimeZone, dat de absolute tijdverschuiving bepaalt, bepaalt Locale hoe tijd, getallen en valuta eruitzien in tekstuele weergave. Dezelfde datum 2024-07-21 wordt weergegeven als „21 juli 2024„ voor ru_RU en „July 21, 2024„ voor en_US.
Elk Locale-exemplaar bestaat uit twee componenten: Language (taal — bepaalt maandnamen, dagen van de week, woordvolgorde) en Region (regio — bepaalt getalnotatie, valuta, kalender). De combinatie van deze componenten wordt gecodeerd in de identificatie volgens de BCP 47-standaard: ru_RU (Russisch, Rusland), en_US (Engels, VS), de_DE (Duits, Duitsland).
Volgens Unicode CLDR (2024) overschrijdt de lijst met ondersteunde talenregios in iOS de 700 combinaties van taal-regio. Foundation gebruikt gegevens uit CLDR (Common Locale Data Repository) — de meest complete opslagplaats van lokalisatiegegevens, ondersteund door het Unicode Consortium. Dit garandeert uniformiteit van opmaak op alle Apple-apparaten.
DateFormatter gebruikt Locale voor het selecteren van de juiste maand- en weekdagnamen, het bepalen van de volgorde van datumcomponenten (dag/maand/jaar of maand/dag/jaar) en scheidingstekens. Zonder expliciete opgave van Locale gebruikt DateFormatter de taalregio van het apparaat — dit is correct voor de UI, maar gevaarlijk voor servergegevens waar het formaat vast moet zijn.
| Component | ru_RU | en_US | de_DE |
|---|---|---|---|
| Datum (medium) | 21 juli 2024 | Jul 21, 2024 | 21.07.2024 |
| Getal (1000.5) | 1 000,5 | 1,000.5 | 1.000,5 |
| Valuta (100) | 100,00 ₽ | $100.00 | 100,00 € |
| Kalender | Gregoriaans | Gregoriaans | Gregoriaans |
| Lijstscheidingsteken | ; | , | ; |
NumberFormatter gebruikt Locale voor het bepalen van de decimale scheiding (komma of punt), groeperingsscheiding (spatie, komma, punt) en het valutasymbool. Het negeren van Locale bij het parsen van getallen is een van de veelvoorkomende oorzaken van fouten in internationale apps: het getal „1,5„ betekent „anderhalf„ voor ru_RU, maar voor en_US leest de getalanalyse het als „vijf„ na de komma.
Belangrijk: Calendar gemaakt via Calendar.current erft de taalregio van het apparaat. Calendar(identifier: .gregorian) met expliciet ingestelde locale — de aanbevolen methode voor voorspelbare opmaak. Gebruik bij het werken met ISO 8601-datums altijd Locale(identifier: "en_US_POSIX") — een speciale taalregio voor technische opmaak die niet wordt beïnvloed door regionale instellingen.
Locale-identificatie bestaat uit een taalcode (ISO 639-1, twee tekens) en een regiocode (ISO 3166-1, twee tekens), gescheiden door een onderstrepingsteken. Voorbeelden: ru_RU, en_US, fr_FR, zh_Hans_CN (Chinees, vereenvoudigd schrift, China). Foundation ondersteunt ook identificaties in BCP 47-formaat: ru-RU, en-US, gebruikt in webstandaarden.
Naast volledige identificaties kan Locale alleen op basis van taal worden gemaakt: Locale(identifier: "ru") retourneert een taalregio met Russisch en de standaardregio voor deze taal (meestal Rusland). Idem voor Engels: Locale(identifier: "en") gebruikt de regio VS. Deze aanpak is handig voor het instellen van de opmaaktaal zonder binding aan een specifieke regio.
Speciale taalregios omvatten en_US_POSIX — een technische taalregio voor machineopmaak van datums en getallen, die een stabiel formaat garandeert ongeacht de gebruikersinstellingen. Deze taalregio is verplicht voor het parsen van datums uit server-API's, vooral voor ISO 8601-formaat. Het gebruikt de gregoriaanse kalender, 24-uurs tijdnotatie en de punt als decimale scheiding.
import Foundation
// Beschikbare taalregio-identificaties
let available: [String] = Locale.availableIdentifiers
print("Totaal taalregios: \(available.count)")
// Filter Russische taalregios
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("Russische taalregios: \(russianLocales)")
// Taalregio-componenten
let locale = Locale(identifier: "de_DE")
print("Taal: \(locale.languageCode ?? "nil")")
print("Regio: \(locale.regionCode ?? "nil")")
print("Valuta: \(locale.currencyCode ?? "nil")")
print("Kalender: \(locale.calendar.identifier)")
Controleren van beschikbare taalregios via Locale.availableIdentifiers retourneert een array van alle identificaties die worden ondersteund door de huidige iOS-versie. Voor filteren op regio gebruikt u Locale.availableIdentifiers.filter met controle van regionCode. Dit is handig voor het bouwen van een UI voor regioselectie zonder een vast gecodeerde lijst.
Locale.current — de belangrijkste manier om de huidige taalregio van het apparaat te verkrijgen, ingesteld door de gebruiker in iOS-instellingen (Settings > General > Language & Region). Deze eigenschap wordt automatisch bijgewerkt bij wijziging van taal of regio in de instellingen zonder dat de app opnieuw hoeft te worden gestart. Het kan echter afwijken van de voorkeurstaalregio voor het weergeven van inhoud: een gebruiker kan de interfacetaal op Engels zetten maar datums in Russisch formaat bekijken.
Voor een nauwkeurigere bepaling van gebruikersvoorkeuren gebruikt u Locale.preferredLanguages — een array van talen gesorteerd op gebruikersprioriteit. Het eerste element is de primaire interfacetaal. Deze lijst komt overeen met de instellingen in Language & Region, inclusief het slepen van talen in volgorde van voorkeur. Communicatie-apps (messengers, e-mailclients) moeten deze volgorde in overweging nemen bij het kiezen van de weergavetaal van inhoud.
import Foundation
// Huidige systeemtaalregio
let current = Locale.current
print("Huidige taalregio: \(current.identifier)")
print("Taal: \(current.language?.disjointName ?? "nil")")
// Voorkeurstalen van de gebruiker
let preferred = Locale.preferredLanguages
print("Voorkeurstalen: \(preferred)")
// Regio ophalen van huidige taalregio
if let region = current.regionCode {
let regionLocale = Locale(identifier: "en_\(region)")
let countryName = regionLocale.localizedString(
forRegionCode: region
)
print("Land: \(countryName ?? region)")
}
// Controleer 24u-formaat
let uses24h = current.uses24hClock(
for: .dateAndTime
)
print("Gebruikt 24u: \(uses24h)")
Lokalisatie in de UI: voor het weergeven van maand- en weekdagnamen in de interfacetaal gebruikt u Calendar met ingestelde locale. Calendar.current.symbols(for: .month) retourneert maandnamen in de taal van de huidige taalregio. Voor het weergeven van landnamen in de taal van de gebruiker gebruikt u Locale.current.localizedString(forRegionCode:).
Datumopmaak met inachtneming van de taalregio — een belangrijke taak bij het weergeven van datums aan de gebruiker. DateFormatter met ingestelde locale selecteert automatisch het juiste datum- en tijdformaat voor de regio van de gebruiker. Voor dateStyle en timeStyle met waarden .short, .medium, .long, .full gebruikt de formatter de regels van de taalregio voor het samenstellen van datumcomponenten.
import Foundation
let date = Date()
// Opmaak met verschillende taalregios
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("Engels: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "ja_JP")
print("Japans: \(formatter.string(from: date))")
// Valuta-opmaak met taalregio
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency
numFormatter.locale = Locale(identifier: "de_DE")
print("Duitse valuta: \(numFormatter.string(from: 1234.56) ?? "nil")")
numFormatter.locale = Locale(identifier: "en_US")
print("Amerikaanse valuta: \(numFormatter.string(from: 1234.56) ?? "nil")")
Parsen van datums uit server-API's moet altijd Locale(identifier: "en_US_POSIX") gebruiken voor een vast formaat. Servers sturen datums meestal in ISO 8601-formaat met Engelse maandnamen, en het gebruik van de huidige taalregio van het apparaat kan leiden tot parsefouten als de gebruiker zich in een regio met een niet-Engelse taal bevindt. en_US_POSIX garandeert dat parsen niet afhankelijk is van apparaatinstellingen.
import Foundation
// Correct parsen van serverdatums
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("Geparste datum: \(parsed)")
}
// Gelokaliseerde valutanaam
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
forCurrencyCode: "RUB"
)
print("Russische roebel in Amerikaanse taalregio: \(currencyName ?? "nil")")
Extra mogelijkheden: Locale biedt gelokaliseerde beschrijvingen van zijn componenten via methoden localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:) en localizedString(forCalendarIdentifier:). Deze methoden retourneren namen in de taal van de taalregio waarin ze zijn aangeroepen. Bijvoorbeeld: Locale(identifier: "ru_RU").localizedString(forCountryCode: "DE") retourneert „Duitsland„.
Negeren van Locale bij het parsen van getallen — een kritieke fout in internationale apps. NumberFormatter zonder expliciete taalregio gebruikt de huidige taalregio van het apparaat. Als een gebruiker in Rusland „1,5„ invoert, retourneert NumberFormatter.number(from: "1,5") correct 1.5. Maar als dezelfde code wordt uitgevoerd op een apparaat met en_US-taalregio, retourneert het parsen nil, omdat voor en_US de decimale scheiding een punt is.
Ontbreken van en_US_POSIX voor serverdatums leidt tot moeilijk te traceren fouten. DateFormatter met dateFormat en locale = Locale.current kan breken bij gebruikers uit regios waar het datumformaat verschilt van het Amerikaanse. Bijvoorbeeld: in Duitsland kan DateFormatter „21.07.2024„ verwachten terwijl de server „07/21/2024„ stuurt. en_US_POSIX garandeert een vast formaat voor machinaal parsen, ongeacht de regio van de gebruiker.
Vergelijken van datumstrings in plaats van Date gebruiken — nog een veelvoorkomende fout. Ontwikkelaars vergelijken soms tekstuele weergaven van datums uit verschillende taalregios, met onjuiste resultaten tot gevolg. Locale verandert alleen de weergave, niet de absolute waarde van de datum. Vergelijk altijd Date-objecten, niet hun tekstuele weergaven. Voor het vergelijken van datumcomponenten gebruikt u Calendar met expliciet ingestelde locale.
Volgens WWDC 2023 houdt ongeveer 30% van de internationaliseringsproblemen in apps verband met onjuiste configuratie van Locale. Apple raadt aan om altijd expliciet locale in te stellen voor DateFormatter en NumberFormatter bij het werken met servergegevens en Locale.current alleen te gebruiken voor weergave in de UI. Deze eenvoudige praktijk elimineert de meeste fouten met betrekking tot regionale instellingen.
Veelgestelde vragen
Locale — Foundation klasse die culturele en taalkundige opmaakregels vertegenwoordigt: datumformaat, getalnotatie, valuta en meeteenheden. Wordt samen met DateFormatter, NumberFormatter en Calendar gebruikt voor gelokaliseerde gegevensweergave.
Locale bepaalt de weergaveopmaak (taal, regionale conventies), terwijl TimeZone de absolute tijdverschuiving ten opzichte van UTC bepaalt. Locale beïnvloedt de tekstuele weergave, TimeZone de numerieke tijdswaarde. Beide worden samen gebruikt voor volledige datumopmaak.
en_US_POSIX — een speciale taalregio voor technische opmaak die een stabiel formaat garandeert ongeacht gebruikersinstellingen. Verplicht voor het parsen van serverdatums (ISO 8601) en werken met API's waar het formaat voorspelbaar moet zijn.
Locale.availableIdentifiers retourneert een array van strings met identificaties van alle ondersteunde taalregios. Voor filteren op taal gebruikt u filter met hasPrefix, voor het verkrijgen van de regio — Locale(identifier:).regionCode.
NumberFormatter gebruikt Locale voor het bepalen van de decimale scheiding (komma of punt), het valutasymbool en de groeperingsscheiding. Voor een vast formaat stelt u locale in op en_US_POSIX of geeft u de formatter-eigenschappen expliciet op.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook