TimeZone ist eine Foundation-Klasse in iOS und macOS, die Zeitzoneninformationen für die korrekte Zeitumrechnung zwischen geografischen Regionen abstrahiert. Laut Apple Developer Documentation, 2024 bietet TimeZone Methoden zum Arbeiten mit Zeitzonenidentifikatoren (IANA Time Zone Database), UTC-Offsets und Sommerzeitregeln. Die Klasse ist in DateFormatter und Calendar integriert und sorgt beim Formatieren von Daten für die automatische Anwendung der richtigen Zeitzone. Im Gegensatz zur manuellen Offset-Berechnung aktualisiert TimeZone die Daten automatisch, wenn sich die Zeitzone des Geräts ändert.
Wichtige Punkte
TimeZone ist ein Werttyp in Swift, der Informationen über eine geografische Zeitzone bereitstellt: UTC-Offset, Name, Abkürzung und Sommerzeitregeln. In Objective-C heißt die Klasse NSTimeZone. Beide Klassen stützen sich auf die IANA Time Zone Database (auch als Olson-Datenbank bekannt), die die Geschichte der Zeitzonenänderungen seit 1970 enthält.
Jede TimeZone-Instanz speichert einen Zeitzonenidentifikator (z.B. Europe/Moscow), den aktuellen Offset in Sekunden von UTC, das isDaylightSavingTime-Flag und das Datum des nächsten Übergangs. Der Identifikator ist der Primärschlüssel: Bei der Initialisierung von TimeZone(identifier:) lädt das System den entsprechenden Datensatz aus der Zeitzonendatenbank des Geräts.
Laut IANA (2024) enthält die Datenbank mehr als 600 eindeutige Zeitzonenidentifikatoren. Apple liefert mit jeder iOS- und macOS-Version einen Snapshot dieser Datenbank aus und gewährleistet so konsistente Berechnungen auf allen Geräten ohne Netzwerkanfragen.
Architektur von TimeZone in Foundation basiert auf einem zweistufigen System: dem Zeitzonenidentifikator (menschenlesbarer Name) und seiner numerischen Darstellung (UTC-Offset). Das System wählt automatisch die aktuelle Zeitzone aus den Geräteeinstellungen aus, aber der Entwickler kann sie für bestimmte Formatierungsvorgänge überschreiben.
TimeZone ist eng mit Calendar und DateFormatter verbunden. Beim Formatieren eines Datums verwendet DateFormatter die timeZone-Eigenschaft einer TimeZone-Instanz, um einen absoluten Zeitpunkt (Date) in eine Zeichenfolgendarstellung in der gewünschten Zeitzone umzuwandeln. Wenn timeZone nicht gesetzt ist, wird die standardmäßige Systemzeitzone verwendet — TimeZone.current.
| Typ | Initialisierung | Eigenschaften |
|---|---|---|
| Aktuell | TimeZone.current | Aktualisiert automatisch bei Regionswechsel in den Einstellungen, verfolgt Sommerzeit |
| Fest | TimeZone(identifier:) | Unabhängig von der Geräteregion. Wendet den ausgewählten Identifikator konsequent an |
| UTC | TimeZone(secondsFromGMT: 0) | Zeitzone ohne Korrektur. Identifikator: GMT |
| Mit beliebigem Offset | TimeZone(secondsFromGMT: 10800) | Fester Offset in Sekunden. Berücksichtigt keine Sommerzeit |
Wichtiger Hinweis: TimeZone(identifier:) gibt nil für unbekannte Identifikatoren zurück. Dies ist eine häufige Ursache für App-Abstürze — Entwickler vergessen, den optionalen Wert zu behandeln, wenn sie einen ungültigen Identifikator aus Benutzereingaben übergeben. Bei IANA-Identifikatoren ist die Groß-/Kleinschreibung wichtig: Europe/Moscow ist gültig, europe/moscow gibt nil zurück.
Die IANA Time Zone Database verwendet das Format „Region/Stadt“ (Kontinent/Stadt), wobei die Region einer der Kontinente (Africa, America, Asia, Atlantic, Australia, Europe, Indian, Pacific) oder ein Ozean ist und die Stadt der bevölkerungsreichste Ort im Abdeckungsbereich der Zeitzone ist. Dieses Format garantiert Eindeutigkeit und Lesbarkeit des Identifikators.
Neben dem Hauptformat unterstützt TimeZone drei zusätzliche Identifikationsmethoden: Abkürzungen (MSK, EST, PST), dreibuchstabige Zeitzonencodes (GMT, UTC) und numerische Offsets (+0300, -0500). Allerdings sind Abkürzungen mehrdeutig: EST kann entweder Eastern Standard Time (GMT-5) oder Eastern Summer Time (GMT+10) in Australien bedeuten. Apple empfiehlt, ausschließlich IANA-Identifikatoren zu verwenden.
import Foundation
// Alle bekannten Zeitzonenidentifikatoren abrufen
let allIdentifiers: [String] = TimeZone.knownTimeZoneIdentifiers
print("Gesamtzeitzonen: \(allIdentifiers.count)")
// Nach Region filtern
let europeZones = allIdentifiers.filter { $0.hasPrefix("Europe/") }
print("Europäische Zeitzonen: \(europeZones)")
// Abkürzungen (nicht für die Produktion empfohlen)
if let moscowTimeZone = TimeZone(abbreviation: "MSK") {
print("MSK-Sekunden von GMT: \(moscowTimeZone.secondsFromGMT())")
}
// Identifikator nach Offset finden
let utcPlus3 = TimeZone(secondsFromGMT: 10800)
print("Identifikator: \(utcPlus3.identifier)")
Abkürzungen in TimeZone.abbreviationDictionary enthalten Abkürzungen für alle bekannten Zeitzonen, aber dieses Wörterbuch garantiert keine Eindeutigkeit: Der PST-Schlüssel kann entweder America/Los_Angeles oder Pacific/Pago_Pago entsprechen. Verwenden Sie für Produktionscode immer IANA-Identifikatoren.
TimeZone berücksichtigt automatisch die Sommerzeitumstellung (DST) für alle Regionen, in denen sie befolgt wird. Das System verwendet historische Daten aus der IANA Time Zone Database, die genaue Übergangsdaten für jede Zeitzone enthält. Die Eigenschaft isDaylightSavingTime gibt true zurück, wenn sich die Zeitzone gerade in der Sommerzeit befindet.
Die Methode nextDaylightSavingTimeTransition ermöglicht es, das Datum des nächsten Übergangs zu erfahren, was für die Planung zukünftiger Ereignisse nützlich ist. Diese Funktionalitat ist besonders wichtig für Regionen mit häufigen DST-Regeländerungen wie Brasilien oder Marokko — bis 2024 änderte Brasilien die Übergangsdaten jährlich, und die manuelle Berechnung führte zu Fehlern in Anwendungen.
Laut Apple WWDC 2023 aktualisiert die ICU-Bibliothek (International Components for Unicode), die Foundation zugrunde liegt, die DST-Daten mit jedem iOS-Update. Anwendungen sollten Sommerzeitdaten nicht länger als einen Tag nach einem Systemupdate zwischenspeichern — die IANA-Datenbank kann sich auch ohne ein OS-Versionsupdate durch Zeitzonenanpassungen ändern.
import Foundation
// DST für Europe/Moscow prüfen
let moscow = TimeZone(identifier: "Europe/Moscow")!
let now = Date()
let isMoscowDST = moscow.isDaylightSavingTime(for: now)
print("Moskau derzeit in DST: \(isMoscowDST)")
// Nächstes DST-Übergangsdatum abrufen
if let nextTransition = moscow.nextDaylightSavingTimeTransition(
after: now
) {
let dstOffset = moscow.daylightSavingTimeOffset(
for: nextTransition
)
print("Nächster Übergang: \(nextTransition), DST-Offset: \(dstOffset)s")
}
// Sichere Konvertierung mit DST-Bewusstsein
let newYork = TimeZone(identifier: "America/New_York")!
let offsetNY = newYork.secondsFromGMT(for: now)
print("Aktueller Offset NY: \(offsetNY / 3600)h")
Kritische Nuance: secondsFromGMT(for:) berücksichtigt DST für das angegebene Datum, während secondsFromGMT() nur für die aktuelle Zeit gilt. Beim Formatieren historischer Daten verwenden Sie immer die Version mit dem Date-Parameter: secondsFromGMT(for: someHistoricalDate). Der Unterschied kann 1–2 Stunden betragen, was für Protokolle oder historische Daten entscheidend ist.
Formatieren eines Datums mit einer bestimmten Zeitzone ist die häufigste Aufgabe bei der Arbeit mit TimeZone. DateFormatter verwendet die timeZone-Eigenschaft, um ein Date in eine Zeichenfolge umzuwandeln. Wenn timeZone nicht explizit gesetzt ist, verwendet der Formatierer TimeZone.current — die auf dem Gerät des Benutzers eingestellte Zeitzone, was für Serverdaten zu unerwarteten Ergebnissen führen kann.
import Foundation
// Datum in bestimmter Zeitzone formatieren
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("Tokio-Zeit: \(tokyoTime)")
// Verfügbare Identifikatoren für Benutzerauswahl
let displayNames: [(String, String)] = TimeZone.knownTimeZoneIdentifiers
.prefix(20)
.map { ($0, TimeZone(identifier: $0)!.localizedName(
for: .generic, locale: .current
)) }
// Zwei Zeitzonen vergleichen
let london = TimeZone(identifier: "Europe/London")!
let difference = tokyo.secondsFromGMT(for: Date())
- london.secondsFromGMT(for: Date())
print("Tokio-London-Differenz: \(difference / 3600)h")
// Mit Abkürzungswörterbuch arbeiten
let knownAbbrevs = TimeZone.abbreviationDictionary
for (abbr, ident) in knownAbbrevs.sorted(by: { $0.key < $1.key }).prefix(5) {
print("\(abbr) -> \(ident)")
}
Lokalisierter Name einer Zeitzone über localizedName(for:locale:) gibt einen menschenlesbaren Namen in der angegebenen Sprache zurück. Für Europe/Moscow mit russischem Gebietsschema gibt die Methode beispielsweise den russischen Namen „Moskva“ zurück und mit englischem Gebietsschema — „Moscow Time“. Verfügbare Stile: .standard (Standardname), .daylightSaving (Sommerzeit) und .shortGeneric (kurz).
import Foundation
let paris = TimeZone(identifier: "Europe/Paris")!
let nameRU = paris.localizedName(
for: .standard,
locale: Locale(identifier: "ru_RU")
)
print("Russischer Name: \(nameRU)")
// Prüfen, ob Region am selben Tag ist
let isSameDay = Calendar.current.isDate(
Date(),
equalTo: Date(),
toGranularity: .day
)
print("Selber Tag über Zeitzonen hinweg: \(isSameDay)")
Serialisierung des Zeitzonenidentifikators ist die beste Praxis zum Speichern von TimeZone in Datenbanken oder UserDefaults. Speichern Sie den Identifikator (eine Zeichenfolge wie Europe/Moscow), nicht den Offset in Sekunden oder eine Abkürzung. Der Offset kann sich bei DST-Änderungen verschieben, und Abkürzungen sind mehrdeutig. Wiederherstellung: TimeZone(identifier: savedString).
Verwenden eines festen Offsets anstelle eines Zeitzonenidentifikators ist der häufigste Fehler. TimeZone(secondsFromGMT: 10800) berücksichtigt kein DST, daher gibt diese Konstruktion für Europe/Moscow im Sommer einen um 1 Stunde falschen Offset. Verwenden Sie für Regionen mit Sommerzeit immer den IANA-Identifikator.
Fehlende nil-Behandlung bei der Initialisierung von TimeZone(identifier:) ist der zweithäufigste Fehler. Wenn ein Benutzer einen falschen Identifikator eingibt (z.B. „moscow“ statt „Europe/Moscow“), gibt der Konstruktor nil zurück. Ohne Behandlung des optionalen Werts stürzt die App mit einem Laufzeitfehler ab. Verwenden Sie guard let oder TimeZone(identifier:) mit einem bekannten Fallback.
Ignorieren von DST bei der Arbeit mit zukünftigen Daten. TimeZone.secondsFromGMT(for:) ist der einzig korrekte Weg, den Offset für ein bestimmtes Datum zu erhalten. Die Verwendung von secondsFromGMT() ohne Parameter für historische oder zukünftige Daten gibt den Offset für den aktuellen Moment zurück, der möglicherweise nicht dem tatsächlichen Offset am angegebenen Datum entspricht, insbesondere für Regionen, die DST abgeschafft oder eingeführt haben.
Laut Stack Overflow (2024) betreffen etwa 15% der Fragen zu DateFormatter eine falsche timeZone-Konfiguration. Ein typisches Szenario: Der Server sendet ein Datum in UTC, der Entwickler formatiert es ohne Angabe der timeZone des Formatierers, und das Datum wird in der Zeitzone des Geräts angezeigt, was bei Benutzern aus verschiedenen Regionen zu Verwirrung führt. Regel: Legen Sie für Serverdaten immer explizit die timeZone des Formatierers fest.
Häufig gestellte Fragen
TimeZone ist eine Foundation-Klasse zum Arbeiten mit Zeitzonen in iOS und macOS. Sie bietet Informationen über UTC-Offset, Sommerzeitregeln und Zeitzonenidentifikatoren basierend auf der IANA Time Zone Database.
Drei Formate: IANA-Identifikatoren (Europe/Moscow), Abkürzungen (MSK, EST) und numerische Offsets (+0300). Apple empfiehlt die Verwendung von IANA-Identifikatoren als einziges eindeutiges Format für Produktionscode.
Automatisch über die Methoden secondsFromGMT(for:) und isDaylightSavingTime(for:). TimeZone verwendet historische IANA-Daten, die mit jeder iOS-Version aktualisiert werden, und gewährleistet korrekte DST-Übergänge für jedes Datum.
TimeZone.current gibt die vom Benutzer in den Einstellungen ausgewählte Zeitzone zurück (kann von der geografischen abweichen). TimeZone.system gibt die Gerätezeitzone zurück, die automatisch durch den Standort bestimmt wird und vom Benutzer nicht überschrieben werden kann.
TimeZone.current gibt die aktuelle Gerätezeitzone zurück. Um den Identifikator zu erhalten, verwenden Sie die Eigenschaft identifier: TimeZone.current.identifier. Für einen lokalisierten Namen rufen Sie localizedName(for:locale:) auf.
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