DateComponents – wat is het, kalendercomponenten en NSCalendar

Auteur: IT Sectr Gepubliceerd: 2026-07-12 Leestijd: 7 min

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 – structuur voor het opslaan van datumcomponenten (jaar, maand, dag) als optionele integer-velden.
  • Calendar.dateComponents – methode die de opgegeven componenten uit Date extraheert met inachtneming van de tijdzone.
  • Calendar.date(from:) – omgekeerde conversie van DateComponents naar Date met automatische aanvulling van ontbrekende velden.
  • Optionele velden – elk veld van DateComponents kan nil zijn, waardoor onvolledige datums kunnen worden opgegeven.
  • Range en componenten – DateComponents wordt in Calendar gebruikt om het verschil tussen datums te berekenen en datums binnen een bereik te vinden.

Wat zijn DateComponents?

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.

Optionele velden

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.

Datumcomponenten: jaar, maand, dag

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.

CategorieVeldenBereik
Kalenderyear, month, day1..∞, 1..12, 1..31
Tijdhour, minute, second, nanosecond0..23, 0..59, 0..59, 0..999999999
Weekweekday, weekOfMonth, weekOfYear1..7, 1..5, 1..53
Speciaalquarter, yearForWeekOfYear1..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.

DateComponents aanmaken

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.

swift
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.

DateComponents naar Date converteren

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.

swift
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 en DateComponents

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.

swift
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.

DateComponents voorbeelden

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.

Herinnering voor de eerste dag van elke maand

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.

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
    )!
}

// 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.

TaakCalendar-methodeRol van DateComponents
Eerste dag van de maandnextDate(after:matching:)day: 1
Leeftijd berekenendateComponents(from:to:)[.year] uit verschil
Datums groeperendateComponents(_:from:)year + month sleutel
Dag van de week zoekennextDate(after:matching:)weekday: N

Veelgestelde vragen

Waarom retourneert Calendar.date(from:) nil voor DateComponents?

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.

Kunnen DateComponents met elkaar worden vergeleken?

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.

Wat is het verschil tussen DateComponents en Date?

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.

Hoe geef ik alleen jaar en maand op in DateComponents?

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.

Hoe gaat DateComponents om met tijdzones?

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

  • DateComponents – Foundation-structuur voor het opslaan van kalendercomponenten (jaar, maand, dag, uur) als optionele Int?-velden.
  • Calendar.dateComponents extraheert componenten uit Date met inachtneming van de tijdzone en het kalendersysteem.
  • Calendar.date(from:) stelt Date samen uit DateComponents met standaardwaarden voor ontbrekende velden.
  • Optionele velden maken het mogelijk onvolledige datums op te geven – Calendar vult ontbrekende waarden aan.
  • Calendar.nextDate zoekt de volgende datum die overeenkomt met DateComponents – voor herinneringen en terugkerende gebeurtenissen.
  • Leeftijd berekenen via Calendar.dateComponents([.year], from:to:) – de enige correcte manier die rekening houdt met schrikkeljaren.
  • MatchingPolicy controleert het gedrag van Calendar bij het niet-overeenkomen van alle componenten – een belangrijke parameter voor het zoeken naar datums.

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.

Bespreek het project

Lees ook