TimeZone — co to jest, klasa Foundation i strefy czasowe

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

TimeZone — to klasa Foundation w iOS i macOS, abstrahująca informacje o strefach czasowych w celu poprawnej konwersji czasu między regionami geograficznymi. Według Apple Developer Documentation, 2024, TimeZone udostępnia metody do pracy z identyfikatorami stref czasowych (IANA Time Zone Database), przesunięciami względem UTC oraz regułami zmiany czasu na letni. Klasa jest zintegrowana z DateFormatter i Calendar, zapewniając automatyczne zastosowanie właściwej strefy czasowej podczas formatowania dat. W przeciwieństwie do ręcznego obliczania przesunięcia, TimeZone automatycznie aktualizuje dane przy zmianie strefy czasowej urządzenia.

Najważniejsze

  • TimeZone — klasa Foundation do pracy ze strefami czasowymi w iOS i macOS
  • IANA Time Zone Database — główne źródło identyfikatorów stref czasowych (America/New_York, Europe/Moscow)
  • Automatyczna korekta — TimeZone uwzględnia zmianę czasu na letni bez dodatkowego kodu
  • Integracja z DateFormatter — strefa czasowa jest stosowana automatycznie podczas formatowania dat
  • Trzy typy — lokalny (bieżący), stały (określony identyfikatorem) i UTC

Czym jest TimeZone w Foundation?

TimeZone — to typ wartościowy w Swift, dostarczający informacji o geograficznej strefie czasowej: przesunięciu względem UTC, nazwie, skrócie i regułach zmiany czasu na letni. W Objective-C klasa nazywa się NSTimeZone. Obie klasy opierają się na IANA Time Zone Database (znanej również jako baza Olsona), która zawiera historię zmian stref czasowych od 1970 roku.

Każda instancja TimeZone przechowuje identyfikator strefy czasowej (np. Europe/Moscow), bieżące przesunięcie w sekundach od UTC, flagę isDaylightSavingTime oraz datę następnej zmiany. Identyfikator jest kluczem podstawowym: podczas inicjalizacji TimeZone(identifier:) system ładuje odpowiedni wpis z bazy danych stref czasowych urządzenia.

Według danych IANA (2024), baza danych zawiera ponad 600 unikalnych identyfikatorów stref czasowych. Apple dostarcza wycinek tej bazy w każdej wersji iOS i macOS, co gwarantuje jednolitość obliczeń na wszystkich urządzeniach bez konieczności zapytań sieciowych.

Jak działa TimeZone w iOS i macOS?

Architektura TimeZone w Foundation opiera się na dwupoziomowym systemie: identyfikatorze strefy czasowej (nazwa czytelna dla człowieka) i jej reprezentacji numerycznej (przesunięcie od UTC). System automatycznie wybiera bieżącą strefę czasową z ustawień urządzenia, ale programista może ją nadpisać dla konkretnych operacji formatowania.

TimeZone jest ściśle powiązany z Calendar i DateFormatter. Podczas formatowania daty DateFormatter używa właściwości timeZone instancji TimeZone do przekształcenia absolutnego momentu w czasie (Date) na reprezentację tekstową w odpowiedniej strefie czasowej. Jeśli timeZone nie jest ustawiony, używana jest domyślna strefa czasowa systemu — TimeZone.current.

Typy instancji TimeZone

TypInicjalizacjaCechy
BieżącyTimeZone.currentAutomatycznie aktualizuje się przy zmianie regionu w ustawieniach, śledzi zmianę czasu na letni
StałyTimeZone(identifier:)Nie zależy od regionu urządzenia. Stale stosuje wybrany identyfikator
UTCTimeZone(secondsFromGMT: 0)Strefa czasowa bez korekty. Identyfikator: GMT
Z dowolnym przesunięciemTimeZone(secondsFromGMT: 10800)Stałe przesunięcie w sekundach. Nie uwzględnia czasu letniego

Ważny niuans: TimeZone(identifier:) zwraca nil dla nieznanych identyfikatorów. To częsta przyczyna awarii aplikacji — programiści zapominają obsłużyć opcjonalną wartość, przekazując nieprawidłowy identyfikator z danych wprowadzonych przez użytkownika. Dla identyfikatorów IANA wielkość liter ma znaczenie: Europe/Moscow — poprawnie, europe/moscow — nil.

Formaty identyfikatorów stref czasowych

IANA Time Zone Database używa formatu „Region/Miasto" (Continent/City), gdzie region to jeden z kontynentów (Africa, America, Asia, Atlantic, Australia, Europe, Indian, Pacific) lub ocean, a miasto to największa miejscowość w zasięgu strefy czasowej. Ten format gwarantuje unikalność i czytelność identyfikatora.

Oprócz podstawowego formatu, TimeZone obsługuje trzy dodatkowe sposoby identyfikacji: skróty (MSK, EST, PST), trzyliterowe kody stref czasowych (GMT, UTC) oraz numeryczne przesunięcia (+0300, -0500). Jednak skróty są niejednoznaczne: EST może oznaczać zarówno Eastern Standard Time (GMT-5), jak i Eastern Summer Time (GMT+10) w Australii. Apple zaleca używanie wyłącznie identyfikatorów IANA.

swift
import Foundation

// Pobierz wszystkie znane identyfikatory stref czasowych
let allIdentifiers: [String] = TimeZone.knownTimeZoneIdentifiers
print("Łączna liczba stref czasowych: \(allIdentifiers.count)")

// Filtruj według regionu
let europeZones = allIdentifiers.filter { $0.hasPrefix("Europe/") }
print("Strefy europejskie: \(europeZones)")

// Skróty (niezalecane w produkcji)
if let moscowTimeZone = TimeZone(abbreviation: "MSK") {
    print("Sekund MSK od GMT: \(moscowTimeZone.secondsFromGMT())")
}

// Znajdź identyfikator według przesunięcia
let utcPlus3 = TimeZone(secondsFromGMT: 10800)
print("Identyfikator: \(utcPlus3.identifier)")

Skróty w TimeZone.abbreviationDictionary zawierają skróty dla wszystkich znanych stref czasowych, ale ten słownik nie gwarantuje unikalności: klucz PST może odpowiadać zarówno America/Los_Angeles, jak i Pacific/Pago_Pago. W kodzie produkcyjnym zawsze używaj identyfikatorów IANA.

Zmiana czasu na letni a TimeZone

TimeZone automatycznie uwzględnia zmianę czasu na letni i zimowy (DST — Daylight Saving Time) dla wszystkich regionów, w których jest to praktykowane. System używa danych historycznych z IANA Time Zone Database, które zawierają dokładne daty zmian dla każdej strefy czasowej. Właściwość isDaylightSavingTime zwraca true, jeśli strefa czasowa obecnie znajduje się w czasie letnim.

Metoda nextDaylightSavingTimeTransition pozwala sprawdzić datę następnej zmiany, co jest przydatne do planowania przyszłych wydarzeń. Ta funkcjonalność jest szczególnie ważna dla regionów z częstymi zmianami zasad DST, takich jak Brazylia czy Maroko — do 2024 roku Brazylia corocznie zmieniała daty przejścia, a ręczne obliczanie prowadziło do błędów w aplikacjach.

Według danych Apple WWDC 2023, biblioteka ICU (International Components for Unicode), leżąca u podstaw Foundation, aktualizuje dane DST przy każdej aktualizacji iOS. Aplikacje nie powinny przechowywać danych o czasie letnim w pamięci podręcznej dłużej niż jeden dzień po aktualizacji systemu — baza IANA może ulec zmianie nawet bez aktualizacji wersji systemu operacyjnego poprzez korekty stref czasowych.

swift
import Foundation

// Sprawdź DST dla Europy/Moskwy
let moscow = TimeZone(identifier: "Europe/Moscow")!
let now = Date()
let isMoscowDST = moscow.isDaylightSavingTime(for: now)
print("Moskwa obecnie w DST: \(isMoscowDST)")

// Pobierz datę następnej zmiany DST
if let nextTransition = moscow.nextDaylightSavingTimeTransition(
    after: now
) {
    let dstOffset = moscow.daylightSavingTimeOffset(
        for: nextTransition
    )
    print("Następna zmiana: \(nextTransition), przesunięcie DST: \(dstOffset)s")
}

// Bezpieczna konwersja z uwzględnieniem DST
let newYork = TimeZone(identifier: "America/New_York")!
let offsetNY = newYork.secondsFromGMT(for: now)
print("Bieżące przesunięcie NY: \(offsetNY / 3600)h")

Krytyczny niuans: secondsFromGMT(for:) uwzględnia DST dla określonej daty, natomiast secondsFromGMT() — tylko dla bieżącego czasu. Podczas formatowania dat historycznych zawsze używaj wersji z parametrem Date: secondsFromGMT(for: someHistoricalDate). Różnica może wynosić 1–2 godziny, co jest krytyczne dla logów lub danych historycznych.

TimeZone w Swift: przykłady kodu

Formatowanie daty z konkretną strefą czasową — to najczęstsze zadanie podczas pracy z TimeZone. DateFormatter używa właściwości timeZone do przekształcenia Date na tekst. Jeśli timeZone nie zostanie jawnie ustawiony, formatatter używa TimeZone.current — strefy czasowej ustawionej na urządzeniu użytkownika, co może prowadzić do nieoczekiwanych wyników dla danych serwerowych.

swift
import Foundation

// Formatuj datę w określonej strefie czasowej
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

let tokyo = TimeZone(identifier: "Asia/Tokyo")!
formatter.timeZone = tokyo
let tokyoTime = formatter.string(from: Date())
print("Czas w Tokio: \(tokyoTime)")

// Dostępne identyfikatory do wyboru przez użytkownika
let displayNames: [(String, String)] = TimeZone.knownTimeZoneIdentifiers
    .prefix(20)
    .map { ($0, TimeZone(identifier: $0)!.localizedName(
        for: .generic, locale: .current
    )) }

// Porównaj dwie strefy czasowe
let london = TimeZone(identifier: "Europe/London")!
let difference = tokyo.secondsFromGMT(for: Date())
    - london.secondsFromGMT(for: Date())
print("Różnica Tokio-Londyn: \(difference / 3600)h")

// Pracuj ze słownikiem skrótów
let knownAbbrevs = TimeZone.abbreviationDictionary
for (abbr, ident) in knownAbbrevs.sorted(by: { $0.key < $1.key }).prefix(5) {
    print("\(abbr) -> \(ident)")
}

Zlokalizowana nazwa strefy czasowej poprzez localizedName(for:locale:) zwraca czytelną dla człowieka nazwę w określonym języku. Na przykład dla Europe/Moscow z lokalizacją rosyjską metoda zwróci „Moskwa", a z angielską — „Moscow Time". Dostępne są style: .standard (nazwa standardowa), .daylightSaving (czas letni) i .shortGeneric (krótka).

swift
import Foundation

let paris = TimeZone(identifier: "Europe/Paris")!
let nameRU = paris.localizedName(
    for: .standard,
    locale: Locale(identifier: "ru_RU")
)
print("Nazwa rosyjska: \(nameRU)")

// Sprawdź, czy region jest tego samego dnia
let isSameDay = Calendar.current.isDate(
    Date(),
    equalTo: Date(),
    toGranularity: .day
)
print("Ten sam dzień w różnych strefach: \(isSameDay)")

Serializacja identyfikatora strefy czasowej — najlepsza praktyka przechowywania TimeZone w bazach danych lub UserDefaults. Zachowaj identyfikator (ciąg typu Europe/Moscow), a nie przesunięcie w sekundach ani skrót. Przesunięcie może się zmieniać przy zmianie DST, a skrót jest niejednoznaczny. Odtworzenie: TimeZone(identifier: savedString).

Typowe błędy przy pracy z TimeZone

Używanie stałego przesunięcia zamiast identyfikatora strefy czasowej — to najczęstszy błąd. TimeZone(secondsFromGMT: 10800) nie uwzględnia DST, więc dla Europe/Moscow latem ta konstrukcja daje błędne przesunięcie o 1 godzinę. Zawsze używaj identyfikatora IANA dla regionów z czasem letnim.

Brak obsługi nil podczas inicjalizacji TimeZone(identifier:) — drugi najczęstszy błąd. Jeśli użytkownik wprowadził identyfikator z błędem (np. „moscow" zamiast „Europe/Moscow"), konstruktor zwraca nil. Bez obsługi wartości opcjonalnej aplikacja ulega awarii z runtime error. Użyj guard let lub TimeZone(identifier:) ze znanym fallbackiem.

Ignorowanie DST przy pracy z przyszłymi datami. TimeZone.secondsFromGMT(for:) — jedyny poprawny sposób uzyskania przesunięcia dla konkretnej daty. Użycie secondsFromGMT() bez parametru dla dat historycznych lub przyszłych daje przesunięcie dla bieżącego momentu, co może nie odpowiadać rzeczywistemu przesunięciu w danej dacie, szczególnie dla regionów z odwołaniem lub wprowadzeniem DST.

Według danych Stack Overflow (2024), około 15% pytań dotyczących DateFormatter wiąże się z nieprawidłowym ustawieniem timeZone. Typowy scenariusz: serwer wysyła datę w UTC, programista formatuje ją bez ustawienia timeZone formatatora, a data wyświetla się w strefie czasowej urządzenia, powodując zamieszanie u użytkowników z różnych regionów. Zasada: zawsze jawnie ustawiaj timeZone formatatora dla danych serwerowych.

Często zadawane pytania

Czym jest TimeZone w Foundation?

TimeZone — klasa Foundation do pracy ze strefami czasowymi w iOS i macOS. Zapewnia informacje o przesunięciu względem UTC, regułach zmiany czasu na letni i identyfikatorach stref czasowych na podstawie IANA Time Zone Database.

Jakie formaty identyfikatorów obsługuje TimeZone?

Trzy formaty: identyfikatory IANA (Europe/Moscow), skróty (MSK, EST) i numeryczne przesunięcia (+0300). Apple zaleca używanie identyfikatorów IANA jako jedynego jednoznacznego formatu w kodzie produkcyjnym.

Jak TimeZone uwzględnia czas letni?

Automatycznie poprzez metody secondsFromGMT(for:) i isDaylightSavingTime(for:). TimeZone używa danych historycznych IANA, aktualizowanych przy każdej wersji iOS, co gwarantuje poprawne przejścia DST dla dowolnej daty.

Jaka jest różnica między TimeZone.current a TimeZone.system?

TimeZone.current zwraca strefę czasową wybraną przez użytkownika w ustawieniach (może różnić się od geograficznej). TimeZone.system zwraca strefę czasową urządzenia, która jest automatycznie określana na podstawie geopozycji i nie może być nadpisana przez użytkownika.

Jak uzyskać bieżącą strefę czasową w Swift?

TimeZone.current zwraca bieżącą strefę czasową urządzenia. Aby uzyskać identyfikator, użyj właściwości identifier: TimeZone.current.identifier. Aby uzyskać zlokalizowaną nazwę, wywołaj localizedName(for:locale:).

Podsumowanie

  • TimeZone — fundamentalna klasa Foundation do pracy ze strefami czasowymi w iOS i macOS
  • Identyfikatory IANA — jedyny niezawodny sposób określania strefy czasowej (Europe/Moscow, America/New_York)
  • Automatyczne uwzględnianie DST — TimeZone poprawnie obsługuje zmianę czasu na letni poprzez secondsFromGMT(for:)
  • Integracja z DateFormatter — obowiązkowe ustawienie timeZone zapobiega nieprawidłowemu wyświetlaniu dat
  • Zlokalizowane nazwy — metoda localizedName(for:locale:) zwraca nazwę strefy czasowej w żądanym języku
  • Obsługa błędów — inicjalizacja TimeZone(identifier:) zwraca nil dla nieprawidłowych identyfikatorów
  • Przechowywanie identyfikatorów — zachowaj ciąg IANA do serializacji, a nie przesunięcie ani skrót

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ż