Locale — co to jest, klasa Foundation i lokalizacja

Autor: IT Sectr Opublikowano: 2026-07-12 Czas czytania: 9 min

Locale — to klasa Foundation w iOS i macOS, która hermetyzuje lingwistyczne i kulturowe konwencje użytkownika: format dat, liczb, walut i jednostek miar. Według Apple Developer Documentation, 2024, Locale określa, jak DateFormatter wyświetla miesiąc (styczeń lub January), separator dziesiętny w liczbie (przecinek lub kropka) oraz symbol waluty (złoty, dolar lub euro). Każda instancja Locale jest powiązana z identyfikatorem typu ru_RU lub en_US, gdzie pierwsza część to kod języka (ISO 639-1), a druga to kod regionu (ISO 3166-1). W przeciwieństwie do TimeZone, Locale nie wpływa na absolutną wartość czasu, tylko na jego reprezentację tekstową.

Najważniejsze

  • Locale — klasa Foundation dla kulturowych i lingwistycznych ustawień formatowania w iOS i macOS
  • Identyfikator ru_RU — połączenie kodu języka (ISO 639-1) i kodu regionu (ISO 3166-1)
  • DateFormatter i NumberFormatter automatycznie używają Locale do lokalizacji wyników
  • Locale.current — systemowa lokal użytkownika, może być nadpisana dla poszczególnych operacji
  • Stała vs automatyczna aktualizacja — Locale(identifier:) tworzy stałą lokal, Locale.current śledzi zmiany w ustawieniach

Czym jest Locale w Foundation?

Locale — to value-typ w Swift (NSLocale w Objective-C), reprezentujący zestaw reguł formatowania charakterystycznych dla konkretnego języka i regionu. W przeciwieństwie do TimeZone, który określa absolutne przesunięcie czasu, Locale określa, jak czas, liczby i waluta wyglądają w reprezentacji tekstowej. Ta sama data 2024-07-21 zostanie wyświetlona jako „21 lipca 2024 r.„ dla ru_RU i „July 21, 2024„ dla en_US.

Każda instancja Locale składa się z dwóch komponentów: Language (język — określa nazwy miesięcy, dni tygodnia, kolejność słów) i Region (region — określa format liczb, walutę, kalendarz). Kombinacja tych komponentów jest kodowana w identyfikatorze według standardu BCP 47: ru_RU (język rosyjski, Rosja), en_US (angielski, USA), de_DE (niemiecki, Niemcy).

Według Unicode CLDR (2024), lista obsługiwanych lokalizacji w iOS przekracza 700 kombinacji język-region. Foundation wykorzystuje dane z CLDR (Common Locale Data Repository) — najpełniejszego repozytorium danych lokalizacyjnych, wspieranego przez Unicode Consortium. Gwarantuje to jednolitość formatowania na wszystkich urządzeniach Apple.

Jak Locale wpływa na formatowanie dat i liczb?

DateFormatter używa Locale do wyboru prawidłowych nazw miesięcy i dni tygodnia, określenia kolejności komponentów daty (dzień/miesiąc/rok lub miesiąc/dzień/rok) oraz separatorów. Bez jawnego określenia Locale DateFormatter używa lokalizacji urządzenia — jest to poprawne dla UI, ale niebezpieczne dla danych serwerowych, gdzie format musi być stały.

Komponentru_RUen_USde_DE
Data (medium)21 lipca 2024 r.Jul 21, 202421.07.2024
Liczba (1000.5)1 000,51,000.51.000,5
Waluta (100)100,00 ₽$100.00100,00 €
KalendarzGregoriańskiGregoriańskiGregoriański
Separator listy;,;

NumberFormatter używa Locale do określenia separatora dziesiętnego (przecinek lub kropka), separatora grupującego (spacja, przecinek, kropka) i symbolu waluty. Ignorowanie Locale podczas parsowania liczb — jedna z częstych przyczyn błędów w aplikacjach międzynarodowych: liczba „1,5„ oznacza „półtora„ dla ru_RU, ale dla en_US analizator cyfrowy odczyta ją jako „pięć„ po przecinku.

Ważne: Calendar utworzony przez Calendar.current dziedziczy lokalizację urządzenia. Calendar(identifier: .gregorian) z jawnie ustawioną locale — zalecany sposób dla przewidywalnego formatowania. Podczas pracy z datami ISO 8601 zawsze używaj Locale(identifier: "en_US_POSIX") — specjalnej lokalizacji do formatowania technicznego, niepodlegającej wpływom ustawień regionalnych.

Identyfikatory Locale: podstawowe formaty

Identyfikator Locale składa się z kodu języka (ISO 639-1, dwa znaki) i kodu regionu (ISO 3166-1, dwa znaki), rozdzielonych podkreślnikiem. Przykłady: ru_RU, en_US, fr_FR, zh_Hans_CN (chiński, uproszczone pismo, Chiny). Foundation obsługuje również identyfikatory w formacie BCP 47: ru-RU, en-US, używane w standardach internetowych.

Oprócz pełnych identyfikatorów, Locale można utworzyć tylko na podstawie języka: Locale(identifier: "ru") zwróci lokalizację z językiem rosyjskim i domyślnym regionem dla tego języka (zwykle Rosja). Podobnie dla angielskiego: Locale(identifier: "en") używa regionu USA. Takie podejście jest przydatne do ustawienia języka formatowania bez wiązania z konkretnym regionem.

Specjalne lokalizacje obejmują en_US_POSIX — techniczną lokalizację do maszynowego formatowania dat i liczb, gwarantującą stabilny format niezależnie od ustawień użytkownika. Ta lokalizacja jest obowiązkowa do parsowania dat z API serwerowych, szczególnie dla formatu ISO 8601. Używa kalendarza gregoriańskiego, 24-godzinnego formatu czasu i kropki jako separatora dziesiętnego.

swift
import Foundation

// Dostępne identyfikatory lokalizacji
let available: [String] = Locale.availableIdentifiers
print("Łączna liczba lokalizacji: \(available.count)")

// Filtruj rosyjskie lokalizacje
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("Rosyjskie lokalizacje: \(russianLocales)")

// Składniki lokalizacji
let locale = Locale(identifier: "de_DE")
print("Język: \(locale.languageCode ?? "nil")")
print("Region: \(locale.regionCode ?? "nil")")
print("Waluta: \(locale.currencyCode ?? "nil")")
print("Kalendarz: \(locale.calendar.identifier)")

Sprawdzanie dostępnych lokalizacji przez Locale.availableIdentifiers zwraca tablicę wszystkich identyfikatorów obsługiwanych przez bieżącą wersję iOS. Do filtrowania według regionu użyj Locale.availableIdentifiers.filter z sprawdzeniem regionCode. Jest to przydatne do budowania UI wyboru regionu bez sztywno zakodowanej listy.

Określenie bieżącej lokalizacji użytkownika w Swift

Locale.current — podstawowy sposób uzyskania bieżącej lokalizacji urządzenia, ustawionej przez użytkownika w ustawieniach iOS (Settings > General > Language & Region). Ta właściwość automatycznie aktualizuje się przy zmianie języka lub regionu w ustawieniach bez restartu aplikacji. Może jednak nie pokrywać się z lokalizacją preferowaną do wyświetlania treści: użytkownik może ustawić język interfejsu na angielski, ale przeglądać daty w formacie rosyjskim.

Do dokładniejszego określenia preferencji użytkownika użyj Locale.preferredLanguages — tablicy języków uporządkowanych według priorytetu użytkownika. Pierwszy element to główny język interfejsu. Ta lista odpowiada ustawieniom w Language & Region, w tym przeciąganiu języków w kolejności preferencji. Aplikacje komunikacyjne (komunikatory, klienty email) powinny uwzględniać tę kolejność przy wyborze języka wyświetlania treści.

swift
import Foundation

// Bieżąca lokalizacja systemowa
let current = Locale.current
print("Bieżąca lokalizacja: \(current.identifier)")
print("Język: \(current.language?.disjointName ?? "nil")")

// Preferowane języki użytkownika
let preferred = Locale.preferredLanguages
print("Preferowane języki: \(preferred)")

// Pobierz region z bieżącej lokalizacji
if let region = current.regionCode {
    let regionLocale = Locale(identifier: "en_\(region)")
    let countryName = regionLocale.localizedString(
        forRegionCode: region
    )
    print("Kraj: \(countryName ?? region)")
}

// Sprawdź format 24h
let uses24h = current.uses24hClock(
    for: .dateAndTime
)
print("Używa 24h: \(uses24h)")

Lokalizacja w UI: do wyświetlania nazw miesięcy i dni tygodnia w języku interfejsu użyj Calendar z ustawioną locale. Calendar.current.symbols(for: .month) zwróci nazwy miesięcy w języku bieżącej lokalizacji. Do wyświetlania nazw krajów w języku użytkownika użyj Locale.current.localizedString(forRegionCode:).

Locale w Swift: przykłady użycia

Formatowanie daty z uwzględnieniem lokalizacji — kluczowe zadanie przy wyświetlaniu dat użytkownikowi. DateFormatter z ustawioną locale automatycznie wybiera prawidłowy format daty i czasu dla regionu użytkownika. Dla dateStyle i timeStyle z wartościami .short, .medium, .long, .full formatter używa reguł lokalizacji do komponowania składników daty.

swift
import Foundation

let date = Date()

// Formatowanie z różnymi lokalizacjami
let formatter = DateFormatter()
formatter.dateStyle = .medium

formatter.locale = Locale(identifier: "ru_RU")
print("Rosyjski: \(formatter.string(from: date))")

formatter.locale = Locale(identifier: "en_US")
print("Angielski: \(formatter.string(from: date))")

formatter.locale = Locale(identifier: "ja_JP")
print("Japoński: \(formatter.string(from: date))")

// Formatowanie walut z lokalizacją
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency

numFormatter.locale = Locale(identifier: "de_DE")
print("Waluta niemiecka: \(numFormatter.string(from: 1234.56) ?? "nil")")

numFormatter.locale = Locale(identifier: "en_US")
print("Waluta amerykańska: \(numFormatter.string(from: 1234.56) ?? "nil")")

Parsowanie dat z API serwerowych zawsze powinno używać Locale(identifier: "en_US_POSIX") dla stałego formatu. Serwery zazwyczaj wysyłają daty w formacie ISO 8601 z angielskimi nazwami miesięcy, a użycie bieżącej lokalizacji urządzenia może prowadzić do błędu parsowania, jeśli użytkownik znajduje się w regionie z nieangielskim językiem. en_US_POSIX gwarantuje, że parsowanie nie zależy od ustawień urządzenia.

swift
import Foundation

// Poprawne parsowanie dat serwerowych
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("Data po parsowaniu: \(parsed)")
}

// Zlokalizowana nazwa waluty
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
    forCurrencyCode: "RUB"
)
print("Rubel rosyjski w lokalizacji amerykańskiej: \(currencyName ?? "nil")")

Dodatkowe możliwości: Locale udostępnia lokalizowany opis swoich komponentów poprzez metody localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:) i localizedString(forCalendarIdentifier:). Te metody zwracają nazwy w języku tej lokalizacji, w której zostały wywołane. Na przykład Locale(identifier: "ru_RU").localizedString(forCountryCode: "DE") zwróci „Niemcy„.

Typowe błędy podczas pracy z Locale

Ignorowanie Locale podczas parsowania liczb — krytyczny błąd w aplikacjach międzynarodowych. NumberFormatter bez jawnej lokalizacji używa bieżącej lokalizacji urządzenia. Jeśli użytkownik w Rosji wprowadza „1,5„, NumberFormatter.number(from: "1,5") poprawnie zwróci 1.5. Ale jeśli ten sam kod jest wykonywany na urządzeniu z lokalizacją en_US, parsowanie zwróci nil, ponieważ dla en_US separatorem dziesiętnym jest kropka.

Brak en_US_POSIX dla dat serwerowych prowadzi do trudnych do wykrycia błędów. DateFormatter z dateFormat i locale = Locale.current może się zepsuć u użytkowników z regionów, gdzie format daty różni się od amerykańskiego. Na przykład w Niemczech DateFormatter może oczekiwać „21.07.2024„, a serwer przysyła „07/21/2024„. en_US_POSIX gwarantuje stały format dla maszynowego parsowania niezależnie od regionu użytkownika.

Porównywanie tekstowych reprezentacji dat zamiast używania Date — kolejny częsty błąd. Programiści czasami porównują tekstowe reprezentacje dat z różnych lokalizacji, otrzymując nieprawidłowe wyniki. Locale zmienia tylko wyświetlanie, ale nie absolutną wartość daty. Zawsze porównuj obiekty Date, a nie ich reprezentacje tekstowe. Do porównywania składników daty używaj Calendar z jawnie ustawioną locale.

Według WWDC 2023, około 30% problemów z internacjonalizacją w aplikacjach jest związanych z nieprawidłową konfiguracją Locale. Apple zaleca zawsze jawne ustawianie locale dla DateFormatter i NumberFormatter podczas pracy z danymi serwerowymi i używanie Locale.current tylko przy wyświetlaniu w UI. Ta prosta praktyka eliminuje większość błędów związanych z ustawieniami regionalnymi.

Często zadawane pytania

Czym jest Locale w Foundation?

Locale — klasa Foundation reprezentująca kulturowe i lingwistyczne reguły formatowania: format daty, liczb, waluty i jednostek miar. Używana razem z DateFormatter, NumberFormatter i Calendar do lokalizowanego wyświetlania danych.

Jaka jest różnica między Locale a TimeZone?

Locale określa format wyświetlania (język, konwencje regionalne), a TimeZone — absolutne przesunięcie czasu względem UTC. Locale wpływa na reprezentację tekstową, TimeZone — na numeryczną wartość czasu. Oba są używane razem do pełnego formatowania daty.

Czym jest en_US_POSIX i do czego służy?

en_US_POSIX — specjalna lokalizacja do formatowania technicznego, gwarantująca stabilny format niezależnie od ustawień użytkownika. Obowiązkowa do parsowania dat serwerowych (ISO 8601) i pracy z API, gdzie format musi być przewidywalny.

Jak uzyskać listę wszystkich dostępnych lokalizacji?

Locale.availableIdentifiers zwraca tablicę ciągów z identyfikatorami wszystkich obsługiwanych lokalizacji. Do filtrowania według języka użyj filter z hasPrefix, a do uzyskania regionu — Locale(identifier:).regionCode.

Jak Locale wpływa na NumberFormatter?

NumberFormatter używa Locale do określenia separatora dziesiętnego (przecinek lub kropka), symbolu waluty i separatora grupującego. Dla stałego formatu ustawiaj locale na en_US_POSIX lub jawnie określaj właściwości formattera.

Podsumowanie

  • Locale — fundamentalna klasa do lokalizacji formatowania dat, liczb i walut w iOS i macOS
  • Identyfikator ru_RU koduje język (ISO 639-1) i region (ISO 3166-1) dla precyzyjnego dostrojenia formatowania
  • DateFormatter i NumberFormatter automatycznie używają Locale.current do lokalizowanego wyświetlania
  • en_US_POSIX — obowiązkowa lokalizacja do parsowania dat serwerowych i stałego formatowania maszynowego
  • Locale.current śledzi zmiany w ustawieniach, Locale(identifier:) tworzy stałą lokalizację
  • Parsowanie liczb wymaga jawnego ustawienia locale — separator dziesiętny zależy od regionu użytkownika
  • Calendar.current dziedziczy lokalizację urządzenia; dla przewidywalnych obliczeń ustawiaj locale jawnie

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również