DateIntervalFormatter ist eine Foundation-Klasse in iOS und macOS, die zum Formatieren von Datumsbereichen in lokalisierte Zeichenfolgen entwickelt wurde: „21.–25. Juli 2024“, „vom 21. bis 25. Juli 2024“ oder „Jul 21–25, 2024“. Laut Apple Developer Documentation, 2024 ermittelt DateIntervalFormatter automatisch, welche Datumskomponenten wiederholt werden sollen (wenn der Bereich innerhalb eines Monats liegt, wird der Monat einmal angezeigt), und lokalisiert Trennzeichen und Wortreihenfolge. Im Gegensatz zum manuellen Verketten zweier formatierter Daten berücksichtigt diese Klasse die grammatikalischen Regeln der Sprache. Die Klasse ist seit iOS 8 und macOS 10.10 verfügbar.
Wichtige Punkte
DateIntervalFormatter ist eine Unterklasse von Formatter in Foundation, die ein DateInterval-Objekt (einen Bereich zwischen zwei Daten) nimmt und eine lokalisierte Zeichenfolge zurückgibt, die diesen Bereich beschreibt. Zum Beispiel für den Bereich vom 21. bis 25. Juli 2024 wäre das Ergebnis für de_DE „21.–25. Juli 2024“. Die Klasse gruppiert wiederholte Elemente intelligent: Wenn beide Daten im selben Monat liegen, wird der Monatsname einmal angezeigt.
Der Hauptwert von DateIntervalFormatter ist die automatische Handhabung der Bereichsgrammatik. Beim manuellen Formatieren müsste ein Entwickler Start-/Endmonat/-jahr vergleichen, ein Trennzeichen auswählen (Bindestrich, „bis“, „bis“) und die Deklination behandeln. DateIntervalFormatter erledigt dies automatisch basierend auf CLDR-Daten (Common Locale Data Repository) und reduziert so Fehler in internationalen Anwendungen, insbesondere bei Sprachen mit komplexer Grammatik.
Laut Unicode CLDR v44 (2024) variieren die Regeln zur Formatierung von Datumsintervallen zwischen den Sprachen erheblich. Deutsch verwendet die Präposition „bis“ (21.–25. Juli 2024), Französisch verwendet „au“ (du 21 au 25 juillet 2024), Japanisch verwendet einen Bindestrich (2024 Jul 21–25). DateIntervalFormatter deckt all diese Variationen ohne zusätzlichen Code auf Entwicklerseite ab.
Das Funktionsprinzip von DateIntervalFormatter basiert auf der Analyse von zwei Daten, die einen Bereich bilden, und der Auswahl der optimalen Zeichenfolgendarstellung unter Berücksichtigung des Gebietsschemas. Die Klasse vergleicht Datumskomponenten (Jahr, Monat, Tag) und trifft Gruppierungsentscheidungen: Wenn das Jahr gleich ist, wird es einmal angezeigt; wenn der Monat gleich ist, wird er einmal angezeigt; wenn die Tage unterschiedlich sind, wird eine Tagespanne angezeigt.
| Bereich | de_DE |
|---|---|
| Ein Tag | 21. Juli 2024 |
| Innerhalb eines Monats | 21.–25. Juli 2024 |
| Verschiedene Monate | 21. Juli – 5. August 2024 |
| Verschiedene Jahre | 25. Dezember 2024 – 5. Januar 2025 |
| Mit Uhrzeit | 21. Juli 2024, 14:30–16:45 |
Gruppierungslogik basierend auf CLDR-Vorlagen implementiert. Der Formatierer überprüft die Gleichheit jeder Datumskomponente (Calendar.Component: year, month, day) in der Reihenfolge von der größten zur kleinsten. Sobald eine Komponente abweicht, werden alle kleineren Komponenten für beide Daten angezeigt. Zum Beispiel für den 21.–25. Juli: Jahr stimmt überein, Monat stimmt überein, Tag weicht ab → Monat wird einmal angezeigt, Tage werden für jedes Datum angezeigt.
Wichtiger Hinweis: DateIntervalFormatter unterstützt keine Anpassung des Trennzeichens über die API. Das Trennzeichen wird durch das Gebietsschema bestimmt und kann nicht überschrieben werden. Wenn ein nicht standardmäßiges Trennzeichen erforderlich ist (z. B. „bis“ statt „bis“), müssen Sie die Daten manuell mit DateFormatter formatieren und die Zeichenfolgen mit einem benutzerdefinierten Trennzeichen verketten.
DateIntervalFormatter bietet zwei Stilsätze: dateStyle und timeStyle für jedes Ende des Bereichs. Diese Stile funktionieren ähnlich wie DateFormatter: .none blendet die Komponente aus, .short gibt ein kurzes Format (21.07.2024), .medium (21. Jul 2024), .long (21. Juli 2024), .full (Sonntag, 21. Juli 2024). Durch Kombinieren von dateStyle und timeStyle können verschiedene Detailstufen erreicht werden.
Wichtig: dateStyle und timeStyle werden auf beide Enden des Bereichs gleichermaßen angewendet. Sie können nicht unterschiedliche Stile für Anfang und Ende festlegen (z. B. .medium für Anfang und .short für Ende). Wenn unterschiedliche Stile benötigt werden, müssen Sie jedes Datum mit einem separaten DateFormatter formatieren und die Ergebnisse verketten.
import Foundation
let formatter = DateIntervalFormatter()
// Verschiedene Stilkombinationen
let startDate = Date()
let endDate = Date().addingTimeInterval(345600) // +4 Tage
let interval = DateInterval(start: startDate, end: endDate)
// Nur Datum, mittleres Format
formatter.dateStyle = .medium
formatter.timeStyle = .none
print("Nur Datum: \(formatter.string(from: interval))")
// Kurzes Format mit Uhrzeit
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Kurz mit Uhrzeit: \(formatter.string(from: interval))")
// Vollständiges Format
formatter.dateStyle = .full
formatter.timeStyle = .none
print("Vollständiges Datum: \(formatter.string(from: interval))")
Grundlegende Verwendung von DateIntervalFormatter umfasst das Erstellen einer Instanz, das Festlegen von Stilen und das Aufrufen von string(from:). Die Methode akzeptiert DateInterval, eine Struktur mit start- und end-Eigenschaften. DateInterval kann aus zwei Date-Werten erstellt oder mit Duration (iOS 16+) initialisiert werden. Nach der Formatierung ist das Ergebnis ohne zusätzliche Verarbeitung für die UI-Anzeige bereit.
import Foundation
let calendar = Calendar.current
let now = Date()
// Spezifische Intervallbeispiele
let examples: [(title: String, start: Date, end: Date)] = [
(
"2-hour event",
now,
now.addingTimeInterval(7200)
),
(
"Week-long vacation",
now,
now.addingTimeInterval(604800)
),
(
"Cross-year period",
calendar.date(from: DateComponents(
year: 2024, month: 12, day: 25
))!,
calendar.date(from: DateComponents(
year: 2025, month: 1, day: 5
))!
)
]
let intervalFormatter = DateIntervalFormatter()
intervalFormatter.dateStyle = .medium
intervalFormatter.timeStyle = .short
for (title, start, end) in examples {
let interval = DateInterval(start: start, end: end)
let result = intervalFormatter.string(from: interval)
print("\(title): \(result)")
}
// Formatierung via Calendar (iOS 16+)
if let nextWeek = calendar.date(
byAdding: .day, value: 7, to: now
) {
let weekInterval = DateInterval(start: now, end: nextWeek)
print("Nächste 7 Tage: \(intervalFormatter.string(from: weekInterval))")
}
DateIntervalFormatter und Kalenderbuchung: In Buchungsanwendungen (Hotels, Tickets) sind Datumsintervalle ein wichtiges UI-Element. DateIntervalFormatter behandelt jahresübergreifende Intervalle korrekt (z. B. 28. Dezember bis 3. Januar) und gruppiert Monat und Jahr für jedes Datum separat. Für solche Szenarien wird die Verwendung von dateStyle = .medium und timeStyle = .none empfohlen, dem lesbarsten Format für Daten ohne Uhrzeit.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
// Buchungsbeispiele
struct Booking {
let checkIn: Date
let checkOut: Date
var formattedInterval: String {
let interval = DateInterval(start: checkIn, end: checkOut)
return formatter.string(from: interval)
}
}
let booking = Booking(
checkIn: calendar.date(from: DateComponents(
year: 2024, month: 7, day: 21
))!,
checkOut: calendar.date(from: DateComponents(
year: 2024, month: 7, day: 25
))!
)
print("Buchung: \(booking.formattedInterval)")
// Verwendung mit verschiedenen Gebietsschemata
let enFormatter = DateIntervalFormatter()
enFormatter.dateStyle = .medium
enFormatter.timeStyle = .none
enFormatter.locale = Locale(identifier: "en_US")
print("Englisch: \(enFormatter.string(from: interval))")
DateInterval vs DateIntervalFormatter: DateInterval ist eine Struktur, die einen Datumsbereich (Start und Ende) darstellt. DateIntervalFormatter ist ein Formatierer, der diese Struktur in eine Zeichenfolge umwandelt. DateInterval unterstützt auch contains(Date)-Prüfungen und intersection(with:), was für die Buchungslogik (Prüfung von Datumsüberschneidungen) nützlich ist.
DateIntervalFormatter lokalisiert die Ausgabe über die locale-Eigenschaft. Standardmäßig wird Locale.current verwendet, das Gebietsschema des Geräts. Um Intervalle in einer anderen Sprache anzuzeigen (z. B. deutscher Inhalt mit englischer Oberfläche), legen Sie die locale explizit fest. Im Gegensatz zu DateFormatter muss DateIntervalFormatter keine locale für serverseitige Daten festlegen. Es verwendet immer seine interne CLDR-basierte Gruppierungslogik.
Die sprachlichen Unterschiede bei der Formatierung von Datumsintervallen sind deutlich komplexer als bei einzelnen Daten. Deutsch verwendet die Präposition „bis“: vom 21. bis 25. Juli. Englisch verwendet einen einfachen Bindestrich: Jul 21–25. Französisch verwendet die Präposition „au“: du 21 au 25 juillet. Japanisch verwendet einen Bindestrich ohne Präpositionen: Jul 21–25. DateIntervalFormatter deckt all diese Varianten ab.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
let start = Date()
let end = Date().addingTimeInterval(259200) // +3 Tage
let interval = DateInterval(start: start, end: end)
// Verschiedene Gebietsschemata demonstrieren
let localeIds = ["ru_RU", "en_US", "de_DE", "fr_FR", "ja_JP", "zh_CN"]
for localeId in localeIds {
formatter.locale = Locale(identifier: localeId)
print("\(localeId): \(formatter.string(from: interval))")
}
// Lokalisierung von Zeitintervallen
formatter.dateStyle = .none
formatter.timeStyle = .short
let todayStart = Date()
let todayEnd = Date().addingTimeInterval(3600)
let timeInterval = DateInterval(start: todayStart, end: todayEnd)
for localeId in ["ru_RU", "en_US", "de_DE"] {
formatter.locale = Locale(identifier: localeId)
print("\(localeId) Uhrzeit: \(formatter.string(from: timeInterval))")
}
Lokalisierungsdetails: Für Deutsch verwendet DateIntervalFormatter die Präposition „bis“ für lange Formate. Für kurze Formate wird der Bindestrich verwendet. Die Formatwahl hängt vom Kontext ab: Für eine Buchungsliste verwenden Sie .medium, für die Detailansicht .long oder .full.
DateIntervalFormatter füllt die Nische der Formatierung von Datumsbereichen, die von anderen Foundation-Klassen nicht abgedeckt wird. DateFormatter formatiert einzelne Daten, RelativeDateTimeFormatter formatiert relative Daten (vor/in), DateComponentsFormatter formatiert Dauer (2 Stunden 30 Minuten). Jede dieser Klassen löst eine bestimmte Aufgabe und kann nicht austauschbar verwendet werden.
| Klasse | Zweck | Ausgabebeispiel |
|---|---|---|
| DateIntervalFormatter | Datumsbereich | 21.–25. Juli 2024 |
| DateFormatter | Einzelnes Datum | 21. Juli 2024 |
| RelativeDateTimeFormatter | Relative Zeit | vor 3 Tagen |
| DateComponentsFormatter | Dauer | 2 Stunden 30 Minuten |
| ISO8601DateFormatter | ISO 8601 Format | 2024-07-21T14:30:00Z |
Wann DateIntervalFormatter verwenden: Zur Anzeige von Datumsbereichen in der UI — Hotelbuchungen, Veranstaltungen, Datumsfilterung, Operationsverlauf. Zur Berechnung der Dauer zwischen Daten verwenden Sie DateComponentsFormatter, nicht DateIntervalFormatter, da letzterer nicht für die Anzeige von Dauern ausgelegt ist. DateFormatter sollte nur für einzelne Daten verwendet werden, nicht zum Verketten von zwei formatierten Daten durch Zeichenfolgenverkettung, da dies zum Verlust der Trennzeichenlokalisation führt.
Randfall: DateIntervalFormatter unterstützt keine offenen Intervalle (ohne Enddatum). Wenn das Ende des Bereichs unbekannt ist (z. B. „ab 21. Juli“), verwenden Sie DateFormatter mit der Präposition „ab“. Außerdem unterstützt DateIntervalFormatter keine Intervalle mit Uhrzeitangabe für verschiedene Tage. Die Uhrzeit wird auf jedes Datum separat angewendet, was bei kurzen Intervallen redundant wirken kann.
Häufig gestellte Fragen
DateIntervalFormatter ist eine Foundation-Klasse zum Formatieren von Datumsbereichen in lokalisierte Zeichenfolgen. Verfügbar seit iOS 8, gruppiert es automatisch wiederholte Komponenten (Monat, Jahr) und wählt das richtige Trennzeichen für die Sprache.
Es vergleicht Komponenten vom Jahr zum Tag. Wenn das Jahr übereinstimmt, wird es einmal angezeigt. Wenn der Monat übereinstimmt, wird er einmal angezeigt. Unterschiedliche Tage werden als Bereich angezeigt. Dies ergibt „21.–25. Juli 2024“ anstelle von „21. Juli 2024 – 25. Juli 2024“.
Nein, das Trennzeichen wird durch das Gebietsschema bestimmt und kann nicht über die API angepasst werden. Für ein benutzerdefiniertes Trennzeichen (z. B. „bis“) formatieren Sie jedes Datum mit einem separaten DateFormatter und verketten die Zeichenfolgen manuell.
DateIntervalFormatter formatiert einen Datumsbereich (zwei Daten) als eine Einheit mit Komponentengruppierung. DateFormatter formatiert ein einzelnes Datum. Für Bereiche verwenden Sie immer DateIntervalFormatter, da es die korrekte Trennzeichenlokalisation bietet.
Automatisch — DateIntervalFormatter erkennt, dass die Jahre unterschiedlich sind, und zeigt vollständige Daten für beide Enden an: „25. Dezember 2024 – 5. Januar 2025“. Keine zusätzliche Konfiguration erforderlich, stellen Sie einfach dateStyle ein.
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