DateFormatter: Grundlegende Konzepte, Datumsformatierung und Lokalisierung

Autor: IT Sectr Veröffentlicht: 2026-07-12 Lesezeit: 7 Min.

DateFormatter ist eine Foundation-Klasse, die für die bidirektionale Konvertierung zwischen Date-Objekten und deren Zeichenfolgendarstellung entwickelt wurde. Die Klasse berücksichtigt das Gebietsschema, die Zeitzone und den Kalender des Benutzers und gewährleistet so eine korrekte Anzeige von Daten in jeder Region der Welt. Laut Apple Developer Documentation (2025) unterstützt DateFormatter vier voreingestellte Datums- und Zeitstile sowie vollständig benutzerdefinierte Formate über eine Vorlagenzeichenfolge. Ohne DateFormatter ist es unmöglich, einem Benutzer in einer internationalisierten Anwendung ein Datum korrekt anzuzeigen.

Wichtige Erkenntnisse

  • DateFormatter — eine Klasse zum Konvertieren von Date in Zeichenfolge und zurück mit Unterstützung für Gebietsschema und Zeitzone.
  • dateStyle und timeStyle — voreingestellte Stile (.short, .medium, .long, .full) für schnelle Formatierung.
  • dateFormat — eine Vorlagenzeichenfolge für benutzerdefiniertes Format, angegeben über Unicode-LDML-Symbole.
  • Locale und TimeZone — Eigenschaften des Formatierers, die die regionale Anzeige und Zeitzone bestimmen.
  • ISO8601DateFormatter — eine schnellere Alternative für das ISO-8601-Format bei der Serialisierung in APIs.

Was ist DateFormatter?

DateFormatter ist eine Klasse aus dem Foundation-Framework, die die bidirektionale Konvertierung zwischen Date und Zeichenfolge implementiert. Sie erschien erstmals in OpenStep als NSDateFormatter und ist seitdem das wichtigste Werkzeug für die Datumsformatierung auf allen Apple-Plattformen. Die Klasse erbt von Formatter und bietet eine praktische API für die lokalisierte Datumsanzeige.

DateFormatter arbeitet auf der Grundlage von Unicode-LDML-Mustern — denselben, die in ICU (International Components for Unicode) verwendet werden. Das Muster wird über die dateFormat-Eigenschaft festgelegt, wobei die Symbole y, M, d, H, m, s für Jahr, Monat, Tag, Stunden, Minuten, Sekunden stehen. Die Wiederholung eines Symbols bestimmt das Format: „y“ — zweistelliges Jahr, „yyyy“ — vierstelliges Jahr.

Das Erstellen eines DateFormatter ist ein teurer Vorgang, da bei der Initialisierung Gebietsschema- und Kalenderdaten geladen werden. Apple empfiehlt, einen Formatierer einmal für jeden Formatierungstyp zu erstellen und wiederzuverwenden. In SwiftUI und UIKit werden Formatierer oft in statischen Eigenschaften zwischengespeichert oder beim ersten Zugriff verzögert erstellt.

DateFormatter im iOS SDK

DateFormatter wird in vielen iOS-Systemkomponenten verwendet. UIDatePicker verwendet DateFormatter intern zur Anzeige von Daten im countDownTimer-Modus. Ein TextField mit einem Formatierer kann automatisch vom Benutzer eingegebene Daten validieren. Core Data unterstützt Attribute vom Typ Date, deren Zeichenfolgendarstellung jedoch immer über DateFormatter erfolgt.

Thread-Sicherheit — DateFormatter ist nicht threadsicher. Das Ändern von Formatierereigenschaften aus verschiedenen Threads führt zu undefiniertem Verhalten. Für die Multithread-Verwendung erstellen Sie separate Formatiererinstanzen für jeden Thread oder verwenden Sie Synchronisierung über NSLock oder eine serielle Warteschlange.

DateFormatter-Formatierungsstile

dateStyle und timeStyle sind die einfachsten Möglichkeiten, die Datumsanzeige zu konfigurieren. Jeder Stil hat vier Varianten: .short, .medium, .long, .full. Die Kombination von dateStyle und timeStyle ermöglicht die unabhängige Konfiguration von Datums- und Zeitformat, und die Eigenschaft .none deaktiviert den entsprechenden Teil.

Für das US-amerikanische Gebietsschema formatiert .short das Datum als „7/21/26“, für das russische als „21.07.2026“. Der Stil .long gibt für das russische Gebietsschema „21. Juli 2026“ aus, und .full gibt „Dienstag, 21. Juli 2026“ mit dem Wochentag aus. Alle vier Stile passen sich automatisch an regionale Standards an, einschließlich der Reihenfolge der Komponenten und Trennzeichen.

SFDateFormatter in iOS 15+ bietet einen alternativen Ansatz über RelativeDateFormatter und DateIntervalFormatter. RelativeDateFormatter gibt „heute“, „gestern“, „in 3 Tagen“ für den aktuellen Kontext aus. DateIntervalFormatter zeigt Datumsbereiche an: „21.–25. Juli 2026“ — für Buchungen und Planung.

StilBeispiel (ru_RU)Beispiel (en_US)
.short21.07.20267/21/26
.medium21. Juli 2026Jul 21, 2026
.long21. Juli 2026July 21, 2026
.fullDienstag, 21. Juli 2026Tuesday, July 21, 2026

Beim Kombinieren von Stilen wählt DateFormatter automatisch das Trennzeichen: für .short.date + .short.time könnte das Ergebnis „21.07.2026, 14:30“ sein. Für .full.date + .full.time — „Dienstag, 21. Juli 2026, 14:30:00 MSK“. Das Trennzeichen wird vom Gebietsschema verwaltet, nicht vom Entwickler — dies gewährleistet die Übereinstimmung mit den regionalen Erwartungen des Benutzers.

Benutzerdefinierte Formate über dateFormat

dateFormat ermöglicht das Festlegen eines beliebigen Formatierungsmusters unter Verwendung von Unicode-LDML-Spezifikationssymbolen. Dies gibt volle Kontrolle über die Anzeige: Sie können nur Jahr und Monat anzeigen, oder den Wochentag ohne Datum, oder die Zeit ohne Sekunden. Benutzerdefiniertes Format ist für spezifische Designanforderungen unverzichtbar.

Hauptsymbole — yyyy (Jahr: 2026), MM (Monat: 07), dd (Tag: 21), HH (Stunden: 14), mm (Minuten: 30), ss (Sekunden: 00). Für den vollständigen Monatsnamen verwenden Sie MMMM (Juli), für die Kurzform — MMM (Jul). Wochentag — EEEE (Dienstag), Kurzform — E (Di).

Bei Verwendung von dateFormat ist es wichtig, das Gebietsschema des Formatierers festzulegen. Wenn kein locale festgelegt ist, verwendet der Formatierer das Systemgebietsschema, was für ein festes Format in einer API unerwünscht sein kann. Apple empfiehlt, locale = Locale(identifier: „en_US_POSIX“) für ein festes regionsübergreifendes Format festzulegen, insbesondere beim Parsen von Daten aus Serverantworten.

swift
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.dateFormat = "d MMMM yyyy"
let customString = formatter.string(from: Date())
// "21 July 2026"

// Eine benutzerdefinierte Zeichenfolge parsen
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = formatter.date(from: "2026-07-21 14:30:00")!

Ein Fehler in dateFormat ist eine der häufigsten Ursachen für App-Abstürze. Wenn das Format nicht mit der Zeichenfolge übereinstimmt, gibt die Methode date(from:) nil zurück. Verwenden Sie guard let oder ?? für sicheres Auspacken von Optionals. Um das Format zu validieren, testen Sie es in allen unterstützten Sprachen — einige LDML-Symbole funktionieren in verschiedenen Gebietsschemata unterschiedlich.

Lokalisierung und TimeZone

Locale bestimmt, wie Monatsnamen, Wochentagsnamen und Trennzeichen angezeigt werden. DateFormatter verwendet standardmäßig Locale.current, aber in einigen Szenarien muss ein bestimmtes Gebietsschema angegeben werden: für ein festes Format in Protokollen verwenden Sie en_US_POSIX, für Serverdaten — das zum Server passende Gebietsschema.

Die Eigenschaft TimeZone bestimmt die Zeitzone für die Anzeige. Standardmäßig wird die Systemzeitzone verwendet, aber für Anwendungen mit internationalem Publikum müssen Daten oft in der Zeitzone des Benutzers oder in UTC angezeigt werden. Das Ändern von timeZone wirkt sich nur auf die Anzeige aus — der Date-Wert bleibt unverändert.

Eine wichtige Funktion: Wenn DateFormatter zum Parsen einer Zeichenfolge verwendet wird und die Zeichenfolge eine Zeitzonenangabe enthält (z. B. „2026-07-21T14:30:00Z“ mit Z für UTC), wird die timeZone-Eigenschaft ignoriert — der Formatierer verwendet die Zeitzone aus der Zeichenfolge. Wenn die Zeitzone in der Zeichenfolge fehlt, wird die timeZone des Formatierers angewendet.

swift
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.timeZone = TimeZone(identifier: "Europe/Moscow")
formatter.dateStyle = .long
formatter.timeStyle = .short

let moscowTime = formatter.string(from: Date())
// "21 July 2026, 14:30"

// Ohne Zeitzone in der Zeichenfolge parsen
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let utcDate = formatter.date(from: "2026-07-21 10:30")!

AutoupdatingCurrentLocale — ein spezieller Gebietsschematyp, der automatisch aktualisiert wird, wenn sich die Systemeinstellungen des Benutzers ändern. DateFormatter unterstützt dies standardmäßig. Wenn die App im Hintergrund läuft und der Benutzer die Systemsprache ändert, verwendet ein vor der Änderung erstellter Formatierer weiterhin das alte Gebietsschema — zum Aktualisieren muss eine neue Instanz erstellt werden.

ISO8601DateFormatter und Alternativen

ISO8601DateFormatter ist ein spezialisierter Formatierer für die Arbeit mit Daten im ISO-8601-Format. Dieses Format ist der De-facto-Standard für REST-APIs, JSON und Datenaustausch. ISO8601DateFormatter arbeitet deutlich schneller als DateFormatter, da es nicht von Gebietsschemata abhängt und eine feste Parsing-Grammatik verwendet.

Hauptoptionen des Formatierers — .withInternetDateTime (2026-07-21T14:30:00Z), .withFractionalSeconds (fügt Millisekunden hinzu), .withTimeZone (enthält Zeitzonenoffset). Durch Kombinieren von Optionen können Sie jede ISO-8601-Variante erhalten: mit Millisekunden, mit Zeitzone, nur mit Datum.

JSONEncoder.DateEncodingStrategy ermöglicht die globale Konfiguration der Datumscodierung für alle Codable-Modelle. Optionen — .iso8601 (verwendet ISO8601DateFormatter), .formatted(DateFormatter), .millisecondsSince1970, .secondsSince1970. Die Wahl der Strategie beeinflusst den gesamten Serialisierungslebenszyklus und sollte über alle API-Endpunkte hinweg konsistent sein.

swift
// ISO8601DateFormatter
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let isoString = isoFormatter.string(from: Date())
// "2026-07-21T14:30:00.000Z"

// JSONEncoder mit ISO8601
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601

// Alternative: JSONEncoder mit benutzerdefiniertem Formatierer
let customEncoder = JSONEncoder()
customEncoder.dateEncodingStrategy = .formatted(myFormatter)

DateFormatter vs ISO8601DateFormatter — wählen Sie ISO8601DateFormatter zum Serialisieren und Parsen von Daten in APIs, da es 5-10 Mal schneller ist als DateFormatter und nicht anfällig für Lokalisierungsfehler. Verwenden Sie DateFormatter für die Benutzeroberfläche, wo eine lokalisierte Anzeige mit Monats- und Tagesnamen in der Muttersprache des Benutzers erforderlich ist.

Beispiele für die Datumsformatierung

Betrachten wir reale Szenarien für die Verwendung von DateFormatter in einer iOS-App: Anzeige in einem Nachrichten-Feed, Eingabe eines Geburtsdatums und Export eines Berichts mit Daten in verschiedenen Zeitzonen.

Anzeige des Nachrichtendatums in einer Liste

RelativeDateFormatter ist optimal für Nachrichtenfeeds. Er zeigt „gerade eben“, „vor 5 Minuten“, „gestern“ für aktuelle Nachrichten an und wechselt für ältere zum vollständigen Datum. Die Umschaltschwelle wird über den Kalender konfiguriert: für Nachrichten verwenden Sie eine 24-Stunden-Schwelle, für Messenger — eine Woche.

swift
func formatRelativeDate(_ date: Date) -> String {
    let relative = RelativeDateFormatter()
    relative.unitsStyle = .full

    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .short

    let daysDiff = Calendar.current.dateComponents(
        [.day], from: date, to: Date()
    ).day ?? 0

    return daysDiff < 1
        ? relative.localizedString(for: date, relativeTo: Date())
        : formatter.string(from: date)
}

Eingabe eines Geburtsdatums — ein weiteres häufiges Szenario. DateFormatter wird mit einem bestimmten dateFormat „dd.MM.yyyy“ und locale „ru_RU“ konfiguriert. Beim Parsen der eingegebenen Zeichenfolge ist es wichtig, mögliche Fehler zu behandeln: der Formatierer gibt nil für eine ungültige Zeichenfolge zurück. Nach erfolgreichem Parsen wird das Datum auf einen akzeptablen Bereich überprüft — nicht vor 1900, nicht nach heute.

Export eines Berichts mit Daten erfordert ein festes Format, das unabhängig vom Gebietsschema des Benutzers ist. Verwenden Sie dateFormat „yyyy-MM-dd HH:mm:ss“ mit locale en_US_POSIX und Zeitzone UTC. Dieser Ansatz garantiert, dass die Datei unabhängig von den regionalen Systemeinstellungen in jedem Land korrekt geöffnet wird.

SzenarioFormatiererWichtige Einstellung
Nachrichten-FeedRelativeDateFormatterunitsStyle = .full
DatumeingabeDateFormatterdateFormat + Fallback
API-SerialisierungISO8601DateFormatterwithInternetDateTime
BerichtsexportDateFormatteren_US_POSIX + UTC

Häufig gestellte Fragen

Warum gibt DateFormatter nil für eine gültige Zeichenfolge zurück?

Der häufigste Grund — eine Nichtübereinstimmung zwischen dateFormat und dem Zeichenfolgenformat. Beispielsweise wird das Format „dd.MM.yyyy“ die Zeichenfolge „2026-07-21“ nicht parsen. Der zweite Grund — Nichtübereinstimmung des Gebietsschemas: die Zeichenfolge „July 21, 2026“ wird mit dem Gebietsschema ru_RU nicht geparst. Der dritte — Tippfehler in LDML-Symbolen: verwenden Sie yyyy, nicht YYYY (unterschiedliche Bedeutung).

Sollte ich für jeden Aufruf einen neuen DateFormatter erstellen?

Nein. DateFormatter ist ein schweres Objekt, dessen Initialisierung das Laden von Gebietsschemadaten umfasst. Erstellen Sie eine Instanz pro Formatierungstyp und verwenden Sie sie wieder. Verwenden Sie in einer Multithread-Umgebung Thread-lokalen Speicher oder einen Formatierer-Pool mit einer seriellen Warteschlange zur Synchronisierung.

Wie unterscheidet sich DateFormatter von RelativeDateFormatter?

DateFormatter zeigt ein absolutes Datum an (21. Juli 2026), während RelativeDateFormatter ein relatives Datum anzeigt (heute, gestern, in 3 Tagen). RelativeDateFormatter wurde in iOS 15+ eingeführt und verwendet dieselbe LDML-Vorlage, wählt aber automatisch die relative Anzeige aus.

Wie verarbeite ich Daten ohne Zeitzone von einer API?

Setzen Sie die timeZone des Formatierers vor dem Parsen auf UTC. Wenn der Server ein Datum in lokaler Zeit ohne Zeitzonenangabe zurückgibt, überprüfen Sie die API-Spezifikation — höchstwahrscheinlich ist UTC gemeint. Für ISO 8601 mit Z am Ende ist keine timeZone erforderlich — der Formatierer parst den Offset aus der Zeichenfolge.

Wie mache ich DateFormatter threadsicher?

Verwenden Sie keine einzelne Instanz aus verschiedenen Threads ohne Synchronisierung. Erstellen Sie eine neue Instanz in jedem Thread oder verwenden Sie Thread.current.threadDictionary zur Speicherung. Eine Alternative ist NSLock mit Sperrung für die Dauer von string(from:) und date(from:).

Zusammenfassung

  • DateFormatter — eine Foundation-Klasse zum Konvertieren von Date in Zeichenfolge und zurück mit Gebietsschema-, Zeitzonen- und Kalenderunterstützung.
  • Voreingestellte Stile dateStyle und timeStyle mit den Varianten .short, .medium, .long, .full decken die meisten UI-Szenarien ab.
  • Benutzerdefiniertes dateFormat über LDML-Symbole gibt volle Kontrolle über das Format, erfordert jedoch Vorsicht bei der Lokalisierung.
  • Locale und TimeZone — erforderliche Eigenschaften für korrekte Anzeige: für UI — Systemgebietsschema, für API — en_US_POSIX und UTC.
  • ISO8601DateFormatter — die bevorzugte Wahl für die Datumsserialisierung in APIs aufgrund von Geschwindigkeit und Stabilität.
  • DateFormatter ist nicht threadsicher — verwenden Sie separate Instanzen für jeden Thread oder synchronisieren Sie den Zugriff.
  • RelativeDateFormatter (iOS 15+) — die optimale Lösung für die Anzeige relativer Daten in Nachrichtenfeeds und Messengern.

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.

Projekt besprechen

Lesen Sie auch