DateComponents is een Foundation-structuur die de componenten van een kalenderdatum opslaat als afzonderlijke velden: jaar, maand, dag, uur, minuut, seconde en andere. In tegenstelling tot Date, dat een absoluut moment in de tijd vertegenwoordigt, bevat DateComponents voor mensen leesbare waarden die afhankelijk zijn van de kalender en tijdzone. Volgens Apple Developer Documentation (2025) wordt DateComponents gebruikt als een tussenliggende schakel tussen Date en Calendar – via deze structuur worden kalenderdatums geëxtraheerd en geconstrueerd, worden berekeningen en verschuivingen van datums uitgevoerd zonder handmatige rekenkunde.
Belangrijkste punten
DateComponents is een waardetype in Foundation bedoeld voor het opslaan van kalendercomponenten van tijd. Elke component wordt weergegeven als een optioneel Int-veld: year, month, day, hour, minute, second, nanosecond, weekday, weekOfMonth, weekOfYear, quarter, yearForWeekOfYear en andere.
Het belangrijkste verschil met Date is de koppeling met de kalender. Date slaat absolute tijd op (aantal seconden vanaf de referentiedatum), terwijl DateComponents een voor mensen leesbare representatie is die alleen betekenis heeft in de context van een specifieke Calendar. Dezelfde Date kan worden weergegeven door verschillende DateComponents in verschillende kalenders en tijdzones.
DateComponents is geen zelfstandig tijdtype, maar een gegevenscontainer. Voor interpretatie van DateComponents als datum is een Calendar nodig die begrijpt hoe de componenten zich verhouden tot het kalendersysteem. Calendar.dateComponents(from: Date) voert de extractie van componenten uit, Calendar.date(from: DateComponents) – de omgekeerde samenstelling.
Elk veld van DateComponents is optioneel (Int?), wat fundamenteel is voor het werken met onvolledige datums. Als u alleen het jaar en de maand opgeeft, vult Calendar de ontbrekende velden aan met standaardwaarden: dag = 1, uur = 0, minuut = 0. Dit is handig voor het maken van datums aan het begin van een periode – u hoeft alleen de relevante componenten op te geven.
Bij het vergelijken van DateComponents met de operator == worden alleen de opgegeven (niet-nil) velden vergeleken. Twee DateComponents-structuren met jaar 2026 maar verschillende maanden worden als verschillend beschouwd. isEqual uit NSObjectProtocol wordt niet toegepast voor DateComponents – DateComponents erft niet van NSObject.
Basisvelden van DateComponents omvatten year, month, day, hour, minute, second, nanosecond. Elk veld slaat een numerieke waarde op in de bijbehorende eenheid: jaar – 2026, maand – 1..12, dag – 1..31, uur – 0..23, minuut – 0..59, seconde – 0..59. Nanoseconden kunnen waarden aannemen van 0..999999999.
Weekvelden – weekday (1..7, waarbij 1 = zondag in de Gregoriaanse kalender), weekOfMonth, weekOfYear. Deze velden zijn afhankelijk van Calendar en hebben geen betekenis buiten de context ervan. weekday hangt af van de firstWeekday-instelling van de kalender: in de Nederlandse locale begint de week op maandag (weekday = 2 in het Gregoriaanse systeem), en in de Amerikaanse – op zondag (weekday = 1).
Gespecialiseerde velden – quarter (1..4), yearForWeekOfYear (het jaar waar de week bij hoort), isLeapMonth (logische vlag voor schrikkelmaanden in de Hebreeuwse of Chinese kalender). De velden calendar en timeZone slaan verwijzingen op naar de corresponderende objecten waarmee de structuur is gemaakt.
| Categorie | Velden | Bereik |
|---|---|---|
| Kalender | year, month, day | 1..∞, 1..12, 1..31 |
| Tijd | hour, minute, second, nanosecond | 0..23, 0..59, 0..59, 0..999999999 |
| Week | weekday, weekOfMonth, weekOfYear | 1..7, 1..5, 1..53 |
| Speciaal | quarter, yearForWeekOfYear | 1..4, afhankelijk |
Bij het extraheren van componenten via Calendar.dateComponents is het belangrijk om alleen de benodigde velden op te vragen voor de prestaties. Calendar extraheert alle gevraagde velden in één enkele doorgang – dit is aanzienlijk sneller dan het afzonderlijk aanroepen van Calendar.component voor elk veld.
Initialisatie van DateComponents – de eenvoudigste manier: u maakt een lege structuur en vult de benodigde velden in. Alle niet-opgegeven velden krijgen automatisch nil. Een datum gemaakt uit gedeeltelijke componenten wordt niet gevalideerd in de initialisatiefase – een fout kan alleen optreden bij de conversie naar Date via Calendar.
De initialisator DateComponents(calendar:timeZone:era:year:month:day:hour:minute:second:nanosecond:weekday:…) maakt het mogelijk alle velden in één aanroep in te stellen. Deze initialisator is handig voor het maken van een volledige datum uit kant-en-klare waarden, maar wordt vanwege de leesbaarheid zelden gebruikt met meer dan 5-6 argumenten.
Calendar.dateComponents(_:from:) – de primaire manier om DateComponents uit een bestaande Date te verkrijgen. Het tweede argument is de set componenten die moeten worden geëxtraheerd. Calendar voert kalenderberekeningen uit met inachtneming van de tijdzone en retourneert een structuur met alleen de gevraagde velden; de overige velden blijven nil.
import Foundation
// Maken via veldeninitialisator
var components = DateComponents()
components.year = 2026
components.month = 7
components.day = 21
// Extraheren uit Date
let now = Date()
let extracted = Calendar.current.dateComponents(
[.year, .month, .day],
from: now
)
print("Today: \(extracted.day!).\(extracted.month!).\(extracted.year!)")
// Maken via uitgebreide initialisator
let birthday = DateComponents(
calendar: Calendar.current,
year: 1990, month: 5, day: 15
)
Bij het handmatig aanmaken van DateComponents via velden, controleer altijd Calendar vóór de conversie naar Date. Calendar kan bij conversie date(from:) nil retourneren als de componenten een niet-bestaande datum vormen – bijvoorbeeld 31 februari of 30 februari in een niet-schrikkeljaar. Validatie van de datum is de verantwoordelijkheid van Calendar, niet van DateComponents.
Calendar.date(from:) – de primaire methode voor conversie van DateComponents naar Date. Calendar interpreteert de componenten volgens zijn kalender en tijdzone. Als sommige velden niet zijn ingesteld (nil), gebruikt Calendar standaardwaarden: dag = 1, uur = 0, minuut = 0, seconde = 0.
De methode retourneert een optionele Date – nil treedt op wanneer de componenten elkaar tegenspreken of een ongeldige datum vormen. Typische oorzaken van nil: niet-bestaande datum (32 januari, 29 februari 2023), tegenstrijdige velden (weekday=1, day=5 in één set), onmogelijk jaar voor de gegeven kalender (jaar 0 in de Gregoriaanse kalender).
DateComponents met timeZone – als DateComponents een timeZone bevat, gebruikt Calendar deze bij de conversie. Als timeZone niet is opgegeven, gebruikt Calendar zijn eigen huidige timeZone. Als Calendar.timeZone niet overeenkomt met de verwachte tijdzone van de datum, kan het resultaat enkele uren afwijken – zorg ervoor dat timeZone expliciet is ingesteld in een van de objecten.
let calendar = Calendar(identifier: .gregorian)
// Date maken uit 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)")
}
// Maken met opgave van timeZone
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 voor het verschil tussen datums – een ander scenario voor het gebruik van DateComponents. Calendar.dateComponents([.year, .month, .day], from: Date(), to: futureDate) retourneert het verschil in jaren, maanden en dagen tussen twee datums. Dit is de juiste manier om leeftijd te berekenen in plaats van het delen van TimeInterval door het aantal seconden in een jaar, omdat Calendar rekening houdt met schrikkeljaren.
Calendar – de centrale klasse die met DateComponents werkt. Alle bewerkingen voor extractie, samenstelling en vergelijking van datums verlopen via Calendar. Zonder Calendar is DateComponents slechts een verzameling getallen zonder temporele betekenis. Calendar geeft de componenten interpretatie: het bepaalt dat maand 2 februari is en weekday 2 maandag is.
Calendar.nextDate en Calendar.enumerateDates – twee methoden gebaseerd op DateComponents. nextDate(after: Date(), matching: DateComponents) vindt de volgende datum die overeenkomt met de opgegeven componenten – bijvoorbeeld de volgende maandag na vandaag. enumerateDates(startingAfter:matching:matchingPolicy:using:) doorloopt alle datums die overeenkomen met het patroon tot een opgegeven limiet.
Calendar.dateInterval – een methode die DateInterval retourneert voor de opgegeven component. dateInterval(of: .month, for: Date()) retourneert het begin en einde van de huidige maand. Intern gebruikt deze methode DateComponents om de grenzen van de periode te vinden: het maakt DateComponents met de eerste en laatste dag van de maand en converteert deze naar Date via Calendar.
let calendar = Calendar.current
// Volgende maandag
let nextMonday = calendar.nextDate(
after: Date(),
matching: DateComponents(weekday: 2),
matchingPolicy: .nextTime
)!
// Verschil tussen datums in dagen
let diff = calendar.dateComponents(
[.day], from: Date(), to: nextMonday
)
// Bereik van de maand
let monthInterval = calendar.dateInterval(
of: .month, for: Date()
)!
let startOfMonth = monthInterval.start
let endOfMonth = monthInterval.end
MatchingPolicy – een belangrijke parameter van Calendar-methoden bij het werken met DateComponents. strictPolicy vereist exacte overeenkomst van alle componenten, nextTimePolicy selecteert de volgende overeenkomst in de tijd, nextTimePreservingSmallerComponents behoudt kleinere componenten (minuten, seconden) van de oorspronkelijke datum. De keuze van het beleid beïnvloedt het resultaat van het zoeken naar datums, vooral bij verschuiving door de overgang naar zomertijd.
We bekijken praktische scenario's voor het gebruik van DateComponents in een app. Elk voorbeeld demonstreert een typische taak waarmee een iOS-ontwikkelaar wordt geconfronteerd bij het werken met kalenderdatums.
Calendar.nextDate met DateComponents(day: 1) vindt de eerste dag van de volgende maand. Calendar bepaalt automatisch het aantal dagen in de huidige maand en gaat naar de volgende maand. Gebruik voor terugkerende meldingen enumerateDates of Combine.Timer met een Calendar-sleutel.
func firstDayOfNextMonth(from date: Date) -> Date {
let calendar = Calendar.current
let comps = DateComponents(day: 1)
return calendar.nextDate(
after: date,
matching: comps,
matchingPolicy: .nextTime
)!
}
// Leeftijd berekenen in jaren
func ageInYears(from birthDate: Date) -> Int {
let calendar = Calendar.current
let ageComponents = calendar.dateComponents(
[.year], from: birthDate, to: Date()
)
return ageComponents.year ?? 0
}
// Gebeurtenissen groeperen op jaar en maand
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!)"
}
}
Leeftijd berekenen via Calendar.dateComponents([.year], from:to:) – de enige correcte manier die rekening houdt met schrikkeljaren. Op TimeInterval gebaseerde berekening (seconden / 31536000) geeft een fout voor personen geboren op 29 februari. Calendar bepaalt correct of de verjaardag in het huidige jaar is geweest en retourneert de exacte leeftijd.
Groeperen op jaar en maand – een veelvoorkomende taak voor schermen met geschiedenis of een kalender. DateComponents dient als groepssleutel: u extraheert het jaar en de maand uit de datum van een gebeurtenis, vormt een string-sleutel en groepeert via Dictionary(grouping:). Gebruik voor weergave DateFormatter met het sjabloon „LLLL yyyy” voor de gelokaliseerde maandnaam.
| Taak | Calendar-methode | Rol van DateComponents |
|---|---|---|
| Eerste dag van de maand | nextDate(after:matching:) | day: 1 |
| Leeftijd berekenen | dateComponents(from:to:) | [.year] uit verschil |
| Datums groeperen | dateComponents(_:from:) | year + month sleutel |
| Dag van de week zoeken | nextDate(after:matching:) | weekday: N |
Veelgestelde vragen
Oorzaken: niet-bestaande datum (31 april), tegenstrijdige velden (weekday=1 met day=5), ongeldige combinatie van velden voor de geselecteerde kalender. Calendar probeert de componenten in zijn systeem te interpreteren – als de combinatie onmogelijk is, is het resultaat nil. Gebruik altijd guard let of if let bij conversie.
Ja, via de operator ==. DateComponents implementeert Equatable en vergelijkt alle velden. Twee structuren zijn gelijk als al hun velden gelijk zijn (nil == nil wordt als waar beschouwd). Voor het vergelijken van slechts een deel van de velden – extraheer dezelfde set via Calendar.dateComponents.
Date – een absoluut moment in de tijd zonder koppeling aan een kalender. DateComponents – een reeks voor mensen leesbare getallen (jaar, maand, dag) die alleen betekenis hebben in de context van Calendar. Date kan worden vergeleken, afgetrokken en geserialiseerd naar ISO 8601. DateComponents – een tussentijdse representatie voor interactie met de kalender.
Stel alleen de velden year en month in en laat de rest nil. Bij conversie naar Date via Calendar.date(from:) stelt Calendar automatisch dag = 1, uur = 0, minuut = 0 in. Het resultaat is een Date die overeenkomt met de eerste dag van de opgegeven maand om middernacht.
DateComponents slaat geen informatie over de tijdzone op in de velden – de waarden van de velden (jaar, maand, dag) zijn zelf afhankelijk van de timeZone waarin ze zijn geëxtraheerd. De componenten „21 juli 2026 14:00 MSK” en „21 juli 2026 10:00 UTC” vertegenwoordigen dezelfde Date, maar de DateComponents-velden zijn verschillend.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook