Locale — är en Foundation-klass i iOS och macOS som kapslar in användarens språkliga och kulturella konventioner: format för datum, tal, valutor och måttenheter. Enligt Apple Developer Documentation, 2024 bestämmer Locale hur DateFormatter visar månaden (januari eller January), decimalavskiljaren i ett tal (komma eller punkt) och valutasymbolen (krona, dollar eller euro). Varje Locale-instans är bunden till en identifierare av typen ru_RU eller en_US, där den första delen är språkkoden (ISO 639-1) och den andra delen är regionkoden (ISO 3166-1). Till skillnad från TimeZone påverkar Locale inte det absoluta tidsvärdet, bara dess textrepresentation.
Huvudpunkter
Locale — är en value-typ i Swift (NSLocale i Objective-C) som representerar en uppsättning formateringsregler som är karakteristiska för ett specifikt språk och region. Till skillnad från TimeZone, som bestämmer den absoluta tidsförskjutningen, bestämmer Locale hur tid, tal och valuta ser ut i textrepresentation. Samma datum 2024-07-21 kommer att visas som "21 juli 2024" för ru_RU och "July 21, 2024" för en_US.
Varje Locale-instans består av två komponenter: Language (språk — bestämmer månadsnamn, veckodagar, ordföljd) och Region (region — bestämmer talformat, valuta, kalender). Kombinationen av dessa komponenter kodas i identifieraren enligt BCP 47-standarden: ru_RU (ryska, Ryssland), en_US (engelska, USA), de_DE (tyska, Tyskland).
Enligt Unicode CLDR (2024) överstiger listan över språkinställningar som stöds i iOS 700 kombinationer av språk-region. Foundation använder data från CLDR (Common Locale Data Repository) — det mest kompletta lagret av lokaliseringsdata som stöds av Unicode Consortium. Detta garanterar enhetlighet i formateringen på alla Apple-enheter.
DateFormatter använder Locale för att välja korrekta månads- och veckodagsnamn, bestämma ordningen på datumkomponenter (dag/månad/år eller månad/dag/år) och avskiljare. Utan explicit angivelse av Locale använder DateFormatter enhetens locale — detta är korrekt för gränssnittet men farligt för serverdata där formatet måste vara fast.
| Komponent | ru_RU | en_US | de_DE |
|---|---|---|---|
| Datum (medium) | 21 juli 2024 | Jul 21, 2024 | 21.07.2024 |
| Tal (1000.5) | 1 000,5 | 1,000.5 | 1.000,5 |
| Valuta (100) | 100,00 ₽ | $100.00 | 100,00 € |
| Kalender | Gregoriansk | Gregoriansk | Gregoriansk |
| Listavskiljare | ; | , | ; |
NumberFormatter använder Locale för att bestämma decimalavskiljaren (komma eller punkt), grupperingsavskiljaren (mellanslag, komma, punkt) och valutasymbolen. Att ignorera Locale vid tolkning av tal är en av de vanligaste orsakerna till buggar i internationella appar: talet "1,5" betyder "en och en halv" för ru_RU, men för en_US kommer talanalysatorn att läsa det som "fem" efter kommatecknet.
Viktigt: Calendar som skapas via Calendar.current ärver enhetens locale. Calendar(identifier: .gregorian) med explicit angiven locale — det rekommenderade sättet för förutsägbar formatering. Vid arbete med ISO 8601-datum, använd alltid Locale(identifier: "en_US_POSIX") — en speciell locale för teknisk formatering som inte påverkas av regionala inställningar.
Locale-identifieraren består av en språkkod (ISO 639-1, två tecken) och en regionkod (ISO 3166-1, två tecken), separerade med understreck. Exempel: ru_RU, en_US, fr_FR, zh_Hans_CN (kinesiska, förenklad skrift, Kina). Foundation stöder också identifierare i BCP 47-format: ru-RU, en-US, som används i webbstandarder.
Förutom fullständiga identifierare kan Locale skapas endast baserat på språk: Locale(identifier: "ru") returnerar en locale med ryska och standardregionen för detta språk (vanligtvis Ryssland). Liknande för engelska: Locale(identifier: "en") använder regionen USA. Detta tillvägagångssätt är användbart för att ställa in formateringsspråk utan bindning till en specifik region.
Speciella språkinställningar inkluderar en_US_POSIX — en teknisk locale för maskinformatering av datum och tal, som garanterar ett stabilt format oavsett användarinställningar. Denna locale är obligatorisk för tolkning av datum från server-API:er, särskilt för ISO 8601-format. Den använder gregoriansk kalender, 24-timmars tidsformat och punkt som decimalavskiljare.
import Foundation
// Tillgängliga locale-identifierare
let available: [String] = Locale.availableIdentifiers
print("Totalt antal språkinställningar: \(available.count)")
// Filtrera ryska språkinställningar
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("Ryska språkinställningar: \(russianLocales)")
// Locale-komponenter
let locale = Locale(identifier: "de_DE")
print("Språk: \(locale.languageCode ?? "nil")")
print("Region: \(locale.regionCode ?? "nil")")
print("Valuta: \(locale.currencyCode ?? "nil")")
print("Kalender: \(locale.calendar.identifier)")
Kontroll av tillgängliga språkinställningar via Locale.availableIdentifiers returnerar en array av alla identifierare som stöds av den aktuella iOS-versionen. För filtrering efter region, använd Locale.availableIdentifiers.filter med kontroll av regionCode. Detta är användbart för att bygga ett gränssnitt för regionval utan en hårdkodad lista.
Locale.current — det främsta sättet att hämta enhetens aktuella locale som ställts in av användaren i iOS-inställningarna (Settings > General > Language & Region). Denna egenskap uppdateras automatiskt vid ändring av språk eller region i inställningarna utan omstart av appen. Den kan dock sammanfalla med den föredragna lokalen för att visa innehåll: användaren kan ställa in gränssnittsspråket till engelska men visa datum i ryskt format.
För mer exakt bestämning av användarpreferenser, använd Locale.preferredLanguages — en array av språk sorterade efter användarens prioritet. Det första elementet är huvudspråket för gränssnittet. Denna lista motsvarar inställningarna i Language & Region, inklusive dragning av språk i preferensordning. Kommunikationsappar (meddelandetjänster, e-postklienter) bör ta hänsyn till denna ordning vid val av språk för innehållsvisning.
import Foundation
// Aktuell systemlocale
let current = Locale.current
print("Aktuell locale: \(current.identifier)")
print("Språk: \(current.language?.disjointName ?? "nil")")
// Användarens föredragna språk
let preferred = Locale.preferredLanguages
print("Föredragna språk: \(preferred)")
// Hämta region från aktuell locale
if let region = current.regionCode {
let regionLocale = Locale(identifier: "en_\(region)")
let countryName = regionLocale.localizedString(
forRegionCode: region
)
print("Land: \(countryName ?? region)")
}
// Kontrollera 24h-format
let uses24h = current.uses24hClock(
for: .dateAndTime
)
print("Använder 24h: \(uses24h)")
Lokalisering i gränssnittet: för att visa månads- och veckodagsnamn på gränssnittsspråket, använd Calendar med angiven locale. Calendar.current.symbols(for: .month) returnerar månadsnamn på den aktuella locales språk. För att visa landsnamn på användarens språk, använd Locale.current.localizedString(forRegionCode:).
Datumformatering med hänsyn till locale — en nyckeluppgift vid visning av datum för användaren. DateFormatter med angiven locale väljer automatiskt rätt datum- och tidsformat för användarens region. För dateStyle och timeStyle med värdena .short, .medium, .long, .full använder formateraren locales regler för att komponera datumkomponenter.
import Foundation
let date = Date()
// Formatering med olika språkinställningar
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.locale = Locale(identifier: "ru_RU")
print("Ryska: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "en_US")
print("Engelska: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "ja_JP")
print("Japanska: \(formatter.string(from: date))")
// Valutaformatering med locale
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency
numFormatter.locale = Locale(identifier: "de_DE")
print("Tysk valuta: \(numFormatter.string(from: 1234.56) ?? "nil")")
numFormatter.locale = Locale(identifier: "en_US")
print("Amerikansk valuta: \(numFormatter.string(from: 1234.56) ?? "nil")")
Tolkning av datum från server-API:er bör alltid använda Locale(identifier: "en_US_POSIX") för fast format. Servrar skickar vanligtvis datum i ISO 8601-format med engelska månadsnamn, och användning av enhetens aktuella locale kan leda till tolkningsfel om användaren befinner sig i en region med ett icke-engelskt språk. en_US_POSIX garanterar att tolkningen inte är beroende av enhetsinställningar.
import Foundation
// Korrekt tolkning av serverdatum
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("Tolkat datum: \(parsed)")
}
// Lokaliserat valutanamn
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
forCurrencyCode: "RUB"
)
print("Rysk rubel i amerikansk locale: \(currencyName ?? "nil")")
Ytterligare funktioner: Locale tillhandahåller lokaliserade beskrivningar av sina komponenter genom metoderna localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:) och localizedString(forCalendarIdentifier:). Dessa metoder returnerar namn på språket för den locale där de anropades. Till exempel, Locale(identifier: "ru_RU").localizedString(forCountryCode: "DE") returnerar "Tyskland".
Ignorera Locale vid tolkning av tal — ett kritiskt misstag i internationella appar. NumberFormatter utan explicit locale använder enhetens aktuella locale. Om en användare i Ryssland anger "1,5", returnerar NumberFormatter.number(from: "1,5") korrekt 1.5. Men om samma kod körs på en enhet med en_US-locale, returnerar tolkningen nil, eftersom decimalavskiljaren för en_US är punkt.
Avsaknad av en_US_POSIX för serverdatum leder till svårupptäckta buggar. DateFormatter med dateFormat och locale = Locale.current kan gå sönder för användare från regioner där datumformatet skiljer sig från det amerikanska. Till exempel, i Tyskland kan DateFormatter förvänta sig "21.07.2024" medan servern skickar "07/21/2024". en_US_POSIX garanterar fast format för maskintolkning oavsett användarens region.
Jämförelse av datumsträngar istället för att använda Date — ett annat vanligt misstag. Utvecklare jämför ibland textrepresentationer av datum från olika språkinställningar och får felaktiga resultat. Locale ändrar bara visningen, inte det absoluta datumvärdet. Jämför alltid Date-objekt, inte deras textrepresentationer. För jämförelse av datumkomponenter, använd Calendar med explicit angiven locale.
Enligt WWDC 2023 är cirka 30% av internationaliseringsproblemen i appar relaterade till felaktig konfiguration av Locale. Apple rekommenderar att alltid explicit ange locale för DateFormatter och NumberFormatter vid arbete med serverdata och endast använda Locale.current för visning i gränssnittet. Denna enkla praxis eliminerar de flesta buggar relaterade till regionala inställningar.
Vanliga frågor
Locale — Foundation-klass som representerar kulturella och språkliga formateringsregler: datumformat, talformat, valuta och måttenheter. Används tillsammans med DateFormatter, NumberFormatter och Calendar för lokaliserad datavisning.
Locale bestämmer visningsformatet (språk, regionala konventioner), medan TimeZone bestämmer den absoluta tidsförskjutningen i förhållande till UTC. Locale påverkar textrepresentationen, TimeZone — det numeriska tidsvärdet. Båda används tillsammans för fullständig datumformatering.
en_US_POSIX — en speciell locale för teknisk formatering som garanterar ett stabilt format oavsett användarinställningar. Obligatorisk för tolkning av serverdatum (ISO 8601) och arbete med API:er där formatet måste vara förutsägbart.
Locale.availableIdentifiers returnerar en array med strängar som innehåller identifierare för alla språkinställningar som stöds. För filtrering efter språk, använd filter med hasPrefix, för att hämta region — Locale(identifier:).regionCode.
NumberFormatter använder Locale för att bestämma decimalavskiljaren (komma eller punkt), valutasymbolen och grupperingsavskiljaren. För fast format, ställ in locale till en_US_POSIX eller ange explicit formaterarens egenskaper.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också