DateComponents — was ist das, Kalenderkomponenten und NSCalendar

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

DateComponents ist eine Foundation-Struktur, die Kalenderdatumskomponenten als separate Felder speichert: Jahr, Monat, Tag, Stunde, Minute, Sekunde und andere. Anders als Date, das einen absoluten Zeitpunkt darstellt, enthält DateComponents menschenlesbare Werte, die vom Kalender und der Zeitzone abhängen. Laut Apple Developer Documentation (2025) wird DateComponents als Zwischenglied zwischen Date und Calendar verwendet — darüber werden Kalenderdaten extrahiert und konstruiert, Berechnungen und Datumsverschiebungen ohne manuelle Arithmetik durchgeführt.

Wichtige Punkte

  • DateComponents — eine Struktur zum Speichern von Datumskomponenten (Jahr, Monat, Tag) als optionale Integer-Felder.
  • Calendar.dateComponents — eine Methode, die die angegebenen Komponenten aus Date unter Berücksichtigung der Zeitzone extrahiert.
  • Calendar.date(from:) — Rückumwandlung von DateComponents in Date mit automatischer Vervollständigung fehlender Felder.
  • Optionale Felder — jedes DateComponents-Feld kann nil sein, was die Angabe unvollständiger Daten ermöglicht.
  • Range und Komponenten — DateComponents wird in Calendar verwendet, um die Differenz zwischen Daten zu berechnen und Daten in einem Bereich zu finden.

Was ist DateComponents?

DateComponents ist ein Foundation-Werttyp, der zum Speichern von Kalenderzeitkomponenten entwickelt wurde. Jede Komponente wird durch ein optionales Int-Feld dargestellt: year, month, day, hour, minute, second, nanosecond, weekday, weekOfMonth, weekOfYear, quarter, yearForWeekOfYear und andere.

Der Hauptunterschied zu Date ist die Kalenderbindung. Date speichert absolute Zeit (Anzahl der Sekunden ab dem Referenzdatum), während DateComponents eine menschenlesbare Darstellung ist, die nur im Kontext eines bestimmten Calendar sinnvoll ist. Dasselbe Date kann in verschiedenen Kalendern und Zeitzonen durch unterschiedliche DateComponents dargestellt werden.

DateComponents ist kein eigenständiger Zeittyp, sondern ein Datencontainer. Zur Interpretation von DateComponents als Datum wird ein Calendar benötigt, der versteht, wie die Komponenten mit dem Kalendersystem zusammenhängen. Calendar.dateComponents(from: Date) führt die Komponentenextraktion durch, Calendar.date(from: DateComponents) führt den umgekehrten Zusammenbau durch.

Optionalität der Felder

Jedes DateComponents-Feld ist optional (Int?), was für die Arbeit mit unvollständigen Daten grundlegend ist. Wenn nur Jahr und Monat angegeben werden, füllt Calendar die fehlenden Felder mit Standardwerten: Tag = 1, Stunde = 0, Minute = 0. Dies ist praktisch zum Erstellen von Startdaten für Zeiträume — es müssen nur die relevanten Komponenten angegeben werden.

Beim Vergleich von DateComponents mit dem Operator == werden nur die angegebenen (nicht nil) Felder verglichen. Zwei DateComponents-Strukturen mit demselben Jahr 2026, aber unterschiedlichen Monaten, gelten als unterschiedlich. isEqual aus NSObjectProtocol gilt nicht für DateComponents — DateComponents erbt nicht von NSObject.

Datumskomponenten: Jahr, Monat, Tag

Hauptfelder von DateComponents umfassen year, month, day, hour, minute, second, nanosecond. Jedes Feld speichert einen numerischen Wert in der entsprechenden Einheit: Jahr — 2026, Monat — 1..12, Tag — 1..31, Stunde — 0..23, Minute — 0..59, Sekunde — 0..59. Nanosekunden können von 0 bis 999999999 reichen.

Wochenfelder — weekday (1..7, wobei 1 = Sonntag im gregorianischen Kalender), weekOfMonth, weekOfYear. Diese Felder hängen vom Calendar ab und haben außerhalb seines Kontexts keine Bedeutung. weekday hängt von der firstWeekday-Einstellung des Kalenders ab: im russischen Gebietsschema beginnt die Woche am Montag (weekday = 2 im gregorianischen System), während sie im amerikanischen am Sonntag beginnt (weekday = 1).

Spezialisierte Felder — quarter (1..4), yearForWeekOfYear (das Jahr, zu dem die Woche gehört), isLeapMonth (ein boolesches Flag für Schaltmonate im hebräischen oder chinesischen Kalender). Die Felder calendar und timeZone speichern Verweise auf die entsprechenden Objekte, mit denen die Struktur erstellt wurde.

KategorieFelderBereich
Kalenderyear, month, day1..∞, 1..12, 1..31
Zeithour, minute, second, nanosecond0..23, 0..59, 0..59, 0..999999999
Wocheweekday, weekOfMonth, weekOfYear1..7, 1..5, 1..53
Speziellequarter, yearForWeekOfYear1..4, abhängig

Beim Extrahieren von Komponenten über Calendar.dateComponents ist es wichtig, aus Leistungsgründen nur die benötigten Felder anzufordern. Calendar extrahiert alle angeforderten Felder in einem einzigen Durchlauf — das ist deutlich schneller, als Calendar.component für jedes einzelne Feld aufzurufen.

DateComponents erstellen

DateComponents initialisieren — der einfachste Weg: eine leere Struktur erstellen und die benötigten Felder ausfüllen. Alle nicht angegebenen Felder erhalten automatisch nil. Ein aus partiellen Komponenten erstelltes Datum wird bei der Initialisierung nicht validiert — ein Fehler kann nur bei der Umwandlung in Date über Calendar auftreten.

Der Initialisierer DateComponents(calendar:timeZone:era:year:month:day:hour:minute:second:nanosecond:weekday:…) ermöglicht das Setzen aller Felder in einem einzigen Aufruf. Dieser Initialisierer ist praktisch zum Erstellen eines vollständigen Datums aus vorgegebenen Werten, wird aber aufgrund der Lesbarkeit selten mit mehr als 5-6 Argumenten verwendet.

Calendar.dateComponents(_:from:) — die primäre Methode zum Erhalten von DateComponents aus einem vorhandenen Date. Das zweite Argument ist die Menge der zu extrahierenden Komponenten. Calendar führt die Kalenderberechnungen unter Berücksichtigung der Zeitzone durch und gibt eine Struktur nur mit den angeforderten Feldern zurück; die restlichen Felder bleiben nil.

swift
import Foundation

// Erstellung über Feld-Initialisierer
var components = DateComponents()
components.year = 2026
components.month = 7
components.day = 21

// Extraktion aus Date
let now = Date()
let extracted = Calendar.current.dateComponents(
    [.year, .month, .day],
    from: now
)
print("Today: \(extracted.day!).\(extracted.month!).\(extracted.year!)")

// Erstellung über erweiterten Initialisierer
let birthday = DateComponents(
    calendar: Calendar.current,
    year: 1990, month: 5, day: 15
)

Beim manuellen Erstellen von DateComponents durch Setzen der Felder, überprüfe immer den Calendar vor der Umwandlung in Date. Bei der Umwandlung date(from:) kann Calendar nil zurückgeben, wenn die Komponenten ein nicht existierendes Datum bilden — zum Beispiel den 31. Februar oder den 30. Februar in einem Nicht-Schaltjahr. Die Datumsvalidierung liegt in der Verantwortung von Calendar, nicht von DateComponents.

DateComponents in Date umwandeln

Calendar.date(from:) — die primäre Methode zum Umwandeln von DateComponents in Date. Calendar interpretiert die Komponenten gemäß seinem eigenen Kalender und seiner Zeitzone. Wenn einige Felder nicht gesetzt sind (nil), verwendet Calendar Standardwerte: Tag = 1, Stunde = 0, Minute = 0, Sekunde = 0.

Die Methode gibt ein optionales Date zurück — nil tritt auf, wenn die Komponenten einander widersprechen oder ein ungültiges Datum bilden. Typische Ursachen für nil: nicht existierendes Datum (32. Januar, 29. Februar 2023), widersprüchliche Felder (weekday=1, day=5 im selben Satz), unmögliches Jahr für den gegebenen Kalender (Jahr 0 im gregorianischen Kalender).

DateComponents mit timeZone — wenn DateComponents eine timeZone enthält, verwendet Calendar sie bei der Umwandlung. Wenn keine timeZone angegeben ist, verwendet Calendar seine eigene aktuelle timeZone. Wenn Calendar.timeZone nicht mit der erwarteten Zeitzone des Datums übereinstimmt, kann das Ergebnis um mehrere Stunden abweichen — stelle sicher, dass timeZone explizit in einem der Objekte gesetzt ist.

swift
let calendar = Calendar(identifier: .gregorian)

// Erstellung von Date aus DateComponents
var comps = DateComponents()
comps.year = 2026
comps.month = 12
comps.day = 25
comps.hour = 10

if let date = calendar.date(from: comps) {
    print("Christmas: \(date)")
}

// Erstellung mit timeZone-Angabe
calendar.timeZone = TimeZone(identifier: "UTC")!
let utcComps = DateComponents(
    calendar: calendar, year: 2026, month: 7, day: 21,
    hour: 12
)
let utcDate = calendar.date(from: utcComps)!

Calendar.dateComponents für die Datumsdifferenz — ein weiterer Anwendungsfall von DateComponents. Calendar.dateComponents([.year, .month, .day], from: Date(), to: futureDate) gibt die Differenz in Jahren, Monaten und Tagen zwischen zwei Daten zurück. Dies ist die korrekte Methode zur Altersberechnung, anstatt TimeInterval durch die Anzahl der Sekunden in einem Jahr zu teilen, da Calendar Schaltjahre berücksichtigt.

Calendar und DateComponents

Calendar — die zentrale Klasse, die mit DateComponents arbeitet. Alle Operationen zum Extrahieren, Zusammenbauen und Vergleichen von Daten erfolgen über Calendar. Ohne Calendar ist DateComponents nur eine Menge von Zahlen ohne zeitliche Bedeutung. Calendar gibt den Komponenten ihre Interpretation: es bestimmt, dass Monat 2 der Februar ist und weekday 2 der Montag ist.

Calendar.nextDate und Calendar.enumerateDates — zwei auf DateComponents basierende Methoden. nextDate(after: Date(), matching: DateComponents) findet das nächste Datum, das den angegebenen Komponenten entspricht — zum Beispiel den nächsten Montag nach heute. enumerateDates(startingAfter:matching:matchingPolicy:using:) iteriert über alle Daten, die dem Muster entsprechen, bis zur angegebenen Grenze.

Calendar.dateInterval — eine Methode, die einen DateInterval für die angegebene Komponente zurückgibt. dateInterval(of: .month, for: Date()) gibt den Anfang und das Ende des aktuellen Monats zurück. Intern verwendet diese Methode DateComponents, um die Periodengrenzen zu finden: sie erstellt DateComponents mit dem ersten und letzten Tag des Monats und wandelt sie über Calendar in Date um.

swift
let calendar = Calendar.current

// Nächster Montag
let nextMonday = calendar.nextDate(
    after: Date(),
    matching: DateComponents(weekday: 2),
    matchingPolicy: .nextTime
)!

// Datumsdifferenz in Tagen
let diff = calendar.dateComponents(
    [.day], from: Date(), to: nextMonday
)

// Monatsbereich
let monthInterval = calendar.dateInterval(
    of: .month, for: Date()
)!
let startOfMonth = monthInterval.start
let endOfMonth = monthInterval.end

MatchingPolicy — ein wichtiger Parameter von Calendar-Methoden bei der Arbeit mit DateComponents. strictPolicy erfordert eine genaue Übereinstimmung aller Komponenten, nextTimePolicy wählt die nächste zeitliche Übereinstimmung aus, nextTimePreservingSmallerComponents bewahrt kleinere Komponenten (Minuten, Sekunden) des Ausgangsdatums. Die Wahl der Richtlinie beeinflusst das Ergebnis der Datumssuche, insbesondere bei Verschiebungen durch Sommerzeitumstellungen.

DateComponents Beispiele

Lassen Sie uns praktische Anwendungsfälle von DateComponents in einer Anwendung untersuchen. Jedes Beispiel zeigt eine typische Aufgabe, mit der ein iOS-Entwickler bei der Arbeit mit Kalenderdaten konfrontiert wird.

Erinnerung am ersten Tag jedes Monats

Calendar.nextDate mit DateComponents(day: 1) findet den ersten Tag des nächsten Monats. Calendar bestimmt automatisch die Anzahl der Tage im aktuellen Monat und wechselt zum nächsten. Für wiederkehrende Benachrichtigungen verwenden Sie enumerateDates oder Combine.Timer mit einem Calendar-Schlüssel.

swift
func firstDayOfNextMonth(from date: Date) -> Date {
    let calendar = Calendar.current
    let comps = DateComponents(day: 1)
    return calendar.nextDate(
        after: date,
        matching: comps,
        matchingPolicy: .nextTime
    )!
}

// Altersberechnung in Jahren
func ageInYears(from birthDate: Date) -> Int {
    let calendar = Calendar.current
    let ageComponents = calendar.dateComponents(
        [.year], from: birthDate, to: Date()
    )
    return ageComponents.year ?? 0
}

// Gruppierung von Ereignissen nach Jahr und Monat
func groupEventsByMonth(_ events: [Event]) -> [String: [Event]] {
    let calendar = Calendar.current
    return Dictionary(grouping: events) { event in
        let comps = calendar.dateComponents(
            [.year, .month], from: event.date
        )
        return "\(comps.year!)-\(comps.month!)"
    }
}

Altersberechnung über Calendar.dateComponents([.year], from:to:) — die einzig korrekte Methode, die Schaltjahre berücksichtigt. Die TimeInterval-basierte Berechnung (Sekunden / 31536000) ergibt einen Fehler für Menschen, die am 29. Februar geboren wurden. Calendar bestimmt korrekt, ob der Geburtstag im aktuellen Jahr stattgefunden hat, und gibt das genaue Alter zurück.

Gruppierung nach Jahr und Monat — eine häufige Aufgabe für Verlaufs- oder Kalenderbildschirme. DateComponents dient als Gruppierungsschlüssel: extrahiere Jahr und Monat aus dem Ereignisdatum, bilde einen Zeichenkettenschlüssel und gruppiere über Dictionary(grouping:). Zur Anzeige verwende DateFormatter mit der Vorlage „LLLL yyyy" für einen lokalisierten Monatsnamen.

AufgabeCalendar-MethodeDateComponents Rolle
Erster Tag des MonatsnextDate(after:matching:)day: 1
AltersberechnungdateComponents(from:to:)[.year] aus Differenz
DatumsgruppierungdateComponents(_:from:)year + month Schlüssel
WochentagssuchenextDate(after:matching:)weekday: N

Häufig gestellte Fragen

Warum gibt Calendar.date(from:) nil für DateComponents zurück?

Ursachen: nicht existierendes Datum (31. April), widersprüchliche Felder (weekday=1 mit day=5), ungültige Feldkombination für den gewählten Kalender. Calendar versucht, die Komponenten in seinem System zu interpretieren — wenn die Kombination unmöglich ist, ist das Ergebnis nil. Verwende bei der Umwandlung immer guard let oder if let.

Können DateComponents miteinander verglichen werden?

Ja, über den Operator ==. DateComponents implementiert Equatable und vergleicht alle Felder. Zwei Strukturen sind gleich, wenn alle ihre Felder gleich sind (nil == nil wird als wahr betrachtet). Zum Vergleichen nur einer Teilmenge von Feldern — extrahiere denselben Satz über Calendar.dateComponents.

Wie unterscheidet sich DateComponents von Date?

Date ist ein absoluter Zeitpunkt ohne Kalenderbindung. DateComponents ist eine Menge menschenlesbarer Zahlen (Jahr, Monat, Tag), die nur im Kontext eines Calendar sinnvoll sind. Date kann verglichen, subtrahiert und in ISO 8601 serialisiert werden. DateComponents ist eine Zwischendarstellung für die Interaktion mit dem Kalender.

Wie gibt man nur Jahr und Monat in DateComponents an?

Setze nur die Felder year und month, lasse den Rest als nil. Bei der Umwandlung in Date über Calendar.date(from:) setzt Calendar automatisch Tag = 1, Stunde = 0, Minute = 0. Das Ergebnis ist ein Date, das dem ersten Tag des angegebenen Monats um Mitternacht entspricht.

Wie behandelt DateComponents Zeitzonen?

DateComponents speichert keine Zeitzoneninformationen in seinen Feldern — die Feldwerte (Jahr, Monat, Tag) selbst hängen von der timeZone ab, in der sie extrahiert wurden. Die Komponenten „21. Juli 2026 14:00 MSK" und „21. Juli 2026 10:00 UTC" repräsentieren dasselbe Date, aber die DateComponents-Felder sind unterschiedlich.

Zusammenfassung

  • DateComponents — eine Foundation-Struktur zum Speichern von Kalenderkomponenten (Jahr, Monat, Tag, Stunde) als optionale Int?-Felder.
  • Calendar.dateComponents extrahiert Komponenten aus Date unter Berücksichtigung von Zeitzone und Kalendersystem.
  • Calendar.date(from:) setzt ein Date aus DateComponents zusammen, mit Standardwerten für fehlende Felder.
  • Optionale Felder erlauben die Angabe unvollständiger Daten — Calendar ergänzt fehlende Werte.
  • Calendar.nextDate findet das nächste Datum, das DateComponents entspricht — für Erinnerungen und wiederkehrende Ereignisse.
  • Altersberechnung über Calendar.dateComponents([.year], from:to:) — die einzig korrekte Methode, die Schaltjahre berücksichtigt.
  • MatchingPolicy steuert das Calendar-Verhalten, wenn nicht alle Komponenten übereinstimmen — ein wichtiger Parameter für die Datumssuche.

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