Calendar — wat is het, Date kalender en berekeningen in Swift

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

Calendar — is een Foundation-klasse die het kalendersysteem definieert en methoden biedt voor kalenderberekeningen: het extraheren van datumcomponenten, het berekenen van het verschil tussen datums, het vinden van periodegrenzen en het verschuiven van datums. De kalender verbindt absolute tijd (Date) met menselijk leesbare componenten en houdt rekening met regionale kenmerken: begin van de week, tijdzone en zomertijd. Volgens Apple Developer Documentation (2025) ondersteunt Foundation 17 kalendersystemen — van Gregoriaans tot Boeddhistisch en Japans, wat Calendar een universeel hulpmiddel maakt voor geïnternationaliseerde applicaties.

Belangrijkste punten

  • Calendar — Foundation-klasse voor kalenderberekeningen: componentenextractie, vergelijking en datumverschuiving.
  • Calendar.current — de systeemkalender van de gebruiker, die automatisch rekening houdt met regionale instellingen.
  • 17 kalendersystemen — Foundation ondersteunt Gregoriaans, Boeddhistisch, Japans, Hebreeuws, Islamitisch en andere.
  • Calendar.dateComponents extraheert componenten (jaar, maand, dag) uit Date met inachtneming van de tijdzone.
  • Calendar.dateInterval retourneert de begin- en einddatum van een opgegeven periode (dag, week, maand).

Wat is Calendar in Foundation?

Calendar — is een Foundation-klasse die kalenderberekeningen implementeert op basis van ICU (International Components for Unicode). De kalender bepaalt hoe absolute tijd (Date) wordt afgebeeld op kalendercomponenten: jaar, maand, dag, uur, minuut, seconde. Zonder Calendar is het onmogelijk te weten welk jaar, maand en dag het is — Date zelf bevat deze informatie niet.

De kalender houdt rekening met drie groepen parameters: kalendersysteem (Gregoriaans, Boeddhistisch, Japans), tijdzone en locale. Calendar.current combineert alle drie uit de systeeminstellingen van de gebruiker. Calendar.autoupdatingCurrent is een speciale versie die automatisch wordt bijgewerkt bij wijziging van instellingen zonder herstart van de applicatie via NotificationCenter.

De kalender is een waardetype (value type) in Foundation. Calendar(identifier:) maakt een nieuwe instantie met vaste parameters. De kalender kan worden gekopieerd, vergeleken met == en gebruikt als sleutel in een woordenboek. Dit maakt het mogelijk kalenders met specifieke timeZone- en locale-instellingen te maken voor testdoeleinden.

Calendar en NSCalendar

Calendar — de Swift-versie van Objective-C NSCalendar, met de brug as Calendar / as NSCalendar. In modern Swift wordt overal Calendar gebruikt. NSCalendar blijft voor achterwaartse compatibiliteit met Objective-C API. Calendar heeft een volledige set methoden zonder NS-voorvoegsel, met type-safe argumenten en Swift-optionaliteit.

Thread Safety — Calendar is thread-safe voor lezen. Een gemaakte instantie kan veilig uit meerdere threads worden gelezen. Wijziging van eigenschappen (timeZone, locale) is niet thread-safe — maak voor verschillende configuraties aparte Calendar-instanties.

Soorten kalenders in Foundation

Foundation ondersteunt 17 kalendersystemen via de Calendar.Identifier-enum. Elk systeem heeft zijn eigen regels voor schrikkeljaren, aantal maanden en het begin van het tijdperk. De kalenderkeuze beïnvloedt alle berekeningen: dateComponents, dateInterval, nextDate.

Belangrijkste kalendersystemen:

  • .gregorian — internationale standaard, 12 maanden, 365/366 dagen, tijdperk na Christus.
  • .buddhist — Boeddhistische kalender, gebruikt in Thailand, Cambodja, Laos, tijdperk loopt 543 jaar voor op de Gregoriaanse.
  • .japanese — Japanse kalender volgens keizerlijke regeerperiodes, 12 maanden zoals in de Gregoriaanse.
  • .hebrew — Hebreeuwse kalender, 12/13 maanden, schrikkelmaand Adar II.
  • .islamic — Islamitische kalender, 12 maanmaanden, 354/355 dagen.
  • .indian — Indiase nationale kalender (Saka), 12 maanden.

Calendar(identifier: .gregorian) — meest gebruikt. Het voldoet aan de internationale standaard ISO 8601 en is de standaardkalender in de meeste landen. Gebruik voor applicaties met een internationaal publiek Calendar.current — deze komt automatisch overeen met de systeemkalender van de gebruiker.

IdentificatieTypeGebruiksregio
.gregorianZonne-Internationaal
.buddhistZonne-Thailand, Cambodja
.japaneseZonne-Japan
.hebrewMaan-zonne-Israël
.islamicMaan-Islamitische landen
.chineseMaan-zonne-China

Calendar en DateComponents

DateComponents en Calendar — een onafscheidelijk paar. Calendar.dateComponents(_:from:) extraheert componenten uit Date met inachtneming van de tijdzone van de kalender. Calendar.date(from:) bouwt Date uit DateComponents, waarbij ontbrekende velden worden ingevuld met standaardwaarden: dag = 1, uur = 0, minuut = 0, seconde = 0.

De methode Calendar.component extraheert één component, wat handig is voor snelle controle. Calendar.dateComponents extraheert een set componenten in één aanroep — dit is efficiënter omdat Calendar de kalenderberekeningen één keer uitvoert, niet voor elke component afzonderlijk. Gebruik voor een lijst van 3+ componenten altijd dateComponents.

Calendar.compare vergelijkt twee Date met opgegeven precisie. De parameter toGranularity bepaalt tot welke component de vergelijking wordt uitgevoerd: .year vergelijkt alleen het jaar, .month — jaar en maand, .day — jaar, maand, dag. Dit is handig om te controleren of twee datums tot dezelfde dag behoren, zonder rekening te houden met de tijd.

swift
let calendar = Calendar.current
let now = Date()

// Extractie van één component
let year = calendar.component(.year, from: now)

// Extractie van een set componenten
let comps = calendar.dateComponents(
    [.year, .month, .day], from: now
)

// Vergelijking met dagprecisie
let isSameDay = calendar.compare(date1, to: date2,
                                  toGranularity: .day) == .orderedSame

// Controleer of datum vandaag is
let isToday = calendar.isDateInToday(someDate)

Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — methoden voor relatieve controles. Calendar.isDate(_:inSameDayAs:) controleert of twee datums op dezelfde kalenderdag vallen met inachtneming van de tijdzone van de kalender. Deze methoden gebruiken intern Calendar.compare en zijn geoptimaliseerd voor frequent gebruik.

Calendar berekeningen

Calendar.dateInterval — een van de nuttigste methoden voor analyse en UI. Het retourneert DateInterval voor de opgegeven component: begin en einde van dag, week, maand, jaar. DateInterval bevat start (Date) en end (Date) — de grenzen van de periode. Bijvoorbeeld, dateInterval(of: .weekOfYear, for: Date()) retourneert het begin van maandag en het einde van zondag van de huidige week.

Calendar.date met byAdding — methode voor datumverschuiving. Calendar.date(byAdding: .day, value: 7, to: Date()) retourneert de datum over een week. Calendar.date(byAdding: DateComponents) — een flexibelere versie waarmee meerdere componenten tegelijk kunnen worden verschoven: +1 maand +3 dagen. Calendar houdt automatisch rekening met verschillende maandlengtes en schrikkeljaren.

Calendar.nextDate zoekt de volgende datum die overeenkomt met opgegeven DateComponents. De parameter matchingPolicy bepaalt het gedrag bij niet-overeenkomen: .nextTime — volgende overeenkomst in tijd, .nextTimePreservingSmallerComponents — behoudt minuten en seconden uit de originele datum, .strict — vereist exacte overeenkomst.

swift
let calendar = Calendar.current
let today = Date()

// Begin en einde van de week
let weekInterval = calendar.dateInterval(
    of: .weekOfYear, for: today
)!

// Verschuiving met 1 maand
let nextMonth = calendar.date(
    byAdding: .month, value: 1, to: today
)!

// Verschuiving via DateComponents
var delta = DateComponents()
delta.month = 1
delta.day = 3
let shifted = calendar.date(byAdding: delta, to: today)!

// Volgende vrijdag de 13e
let friday13Components = DateComponents(
    weekday: 6, day: 13
)
let nextFriday13 = calendar.nextDate(
    after: today, matching: friday13Components,
    matchingPolicy: .nextTime
)

EnumerateDates — een krachtige methode voor het itereren van datums volgens een patroon. Calendar.enumerateDates(startingAfter:matching:matchingPolicy:using:) roept een block aan voor elke overeenkomst totdat het block stop = true retourneert. Wordt gebruikt voor het genereren van terugkerende gebeurtenissen in kalenders en schema's. De methode is efficiënter dan een handmatige lus met nextDate omdat deze is geoptimaliseerd door ICU.

TimeZone en Locale

TimeZone — een onlosmakelijk onderdeel van Calendar. De tijdzone bepaalt welke kalendertijd overeenkomt met de absolute Date. Dezelfde Date in UTC en in Moskou geeft verschillende componenten: Date() in UTC kan 10:00 tonen, en in MSK — 13:00. Calendar.timeZone is standaard gelijk aan TimeZone.current.

Locale beïnvloedt de eerste dag van de week, het minimum aantal dagen in de eerste week van het jaar (minDaysInFirstWeek) en de namen van maanden/dagen van de week (bij conversie via DateFormatter). Calendar.locale is standaard gelijk aan Locale.current. In de Nederlandse locale begint de week op maandag, in de Amerikaanse — op zondag.

Calendar.availableIdentifiers retourneert een lijst van alle ondersteunde kalenderidentificaties. static property Calendar.availableCalendarIdentifiers — een array van strings met dezelfde identificaties. Wordt gebruikt voor het bouwen van een UI voor kalenderkeuze en voor het controleren van de beschikbaarheid van een specifiek kalendersysteem op het apparaat.

swift
// Kalender met specifieke tijdzone
var utcCalendar = Calendar(identifier: .gregorian)
utcCalendar.timeZone = TimeZone(identifier: "UTC")!

// Kalender met Russische locale
var russianCalendar = Calendar(identifier: .gregorian)
russianCalendar.locale = Locale(identifier: "ru_RU")

// Eerste weekdag is afhankelijk van locale
let firstWeekday = russianCalendar.firstWeekday
// 2 = maandag (in nl_NL)

// Lijst van beschikbare kalenders
for identifier in Calendar.availableIdentifiers {
    print(identifier)
}

firstWeekday — de eigenschap van Calendar die bepaalt welke dag van de week als eerste wordt beschouwd. In de Nederlandse locale is Sunday = 2 (maandag eerste). In de Amerikaanse is Sunday = 1. Dit beïnvloedt de werking van weekOfMonth en weekOfYear: dezelfde datum kan in verschillende locales aan verschillende weeknummers worden toegewezen. Gebruik voor applicaties met datums Calendar.current of stel firstWeekday expliciet in.

Voorbeelden van werken met Calendar

Laten we praktische scenario's bekijken die de mogelijkheden van Calendar demonstreren. Elk voorbeeld lost een specifieke taak in iOS-ontwikkeling op en toont de juiste manier van kalenderberekeningen.

Controle: valt de datum in deze maand?

Calendar.dateInterval(of: .month, for:) retourneert de grenzen van de huidige maand. Het controleren of Date binnen dit interval valt — de snelste manier om te bepalen of de datum tot de huidige maand behoort. Alternatieve manier — Calendar.compare met granularity .month: als het resultaat .orderedSame is, komt de maand overeen.

swift
func isInCurrentMonth(_ date: Date) -> Bool {
    let calendar = Calendar.current
    let monthInterval = calendar.dateInterval(
        of: .month, for: Date()
    )!
    return monthInterval.contains(date)
}

// Aantal dagen in een maand
func daysInMonth(for date: Date) -> Int {
    let calendar = Calendar.current
    return calendar.range(
        of: .day, in: .month, for: date
    )?.count ?? 0
}

// Toevoegen van maanden met correcte afronding
func addMonths(_ months: Int, to date: Date) -> Date {
    let calendar = Calendar.current
    return calendar.date(
        byAdding: .month, value: months, to: date
    )!
}

Calendar.range(of:in:for:) retourneert het bereik van toegestane waarden voor de opgegeven component in de context van een andere component. Bijvoorbeeld, range(of: .day, in: .month, for: date) retourneert 1..<32 voor maanden met 31 dagen of 1..<29 voor februari van een niet-schrikkeljaar. Dit is de juiste manier om het aantal dagen in een maand te weten te komen, niet het gebruik van hardgecodeerde waarden.

Toevoegen van maanden via Calendar.date(byAdding:value:to:) verwerkt grensdaten correct. Als aan 31 januari 1 maand wordt toegevoegd, retourneert Calendar 28 februari (of 29 in een schrikkeljaar), niet 3 maart, zoals zou gebeuren bij eenvoudige toevoeging van 30 dagen via TimeInterval. Dit is nog een reden om geen TimeInterval te gebruiken voor kalenderberekeningen.

Calendar methodeDoelVoorbeeld
dateIntervalPeriodegrenzenBegin en einde van de maand
range(of:in:for:)ComponentbereikDagen in huidige maand
date(byAdding:)Datumverschuiving+1 maand vanaf vandaag
isDateInTodayControle of vandaagIs de datum vandaag
compare(toGranularity:)Vergelijking met precisieZelfde dag zonder tijd

Veelgestelde vragen

Wat is het verschil tussen Calendar.current en Calendar(identifier: .gregorian)?

Calendar.current retourneert de kalender uit de systeeminstellingen van de gebruiker — deze kan niet-Gregoriaans zijn (bijvoorbeeld Boeddhistisch in Thailand). Calendar(identifier: .gregorian) maakt altijd een Gregoriaanse kalender, ongeacht de instellingen. Gebruik voor het weergeven van datums Calendar.current, voor bedrijfslogica — de expliciet gekozen identificatie.

Waarom retourneert Calendar.date(byAdding: .month, value: 1) soms dezelfde datum?

Dit komt door de verschillende lengte van maanden. Als de huidige datum 31 januari is, geeft het toevoegen van 1 maand 28 februari, omdat februari geen 31 dagen heeft. Calendar vult de datum automatisch aan tot de laatste toegestane dag van de maand. Gebruik voor nauwkeurige controle DateComponents met day: 1 om naar de eerste dag van de maand te gaan.

Welke kalender gebruikt DateFormatter standaard?

DateFormatter gebruikt Calendar.current — de systeemkalender van de gebruiker. Als de applicatie altijd datums in de Gregoriaanse kalender moet tonen ongeacht de instellingen, stel dan formatter.calendar = Calendar(identifier: .gregorian) in. Dit garandeert een uniforme weergave voor alle gebruikers.

Hoe controleer ik via Calendar of een jaar een schrikkeljaar is?

Calendar.range(of: .day, in: .year, for: date) retourneert 365 of 366 dagen. Eenvoudiger: Calendar.date(from: DateComponents(year: jaar, month: 2, day: 29)) != nil — als 29 februari bestaat, is het jaar een schrikkeljaar. Calendar houdt zelf rekening met de regels voor het specifieke kalendersysteem.

Kan firstWeekday worden gewijzigd na het maken van Calendar?

Ja, de eigenschap firstWeekday is beschrijfbaar. Wijziging beïnvloedt weekOfMonth, weekOfYear en alle berekeningen met betrekking tot weeknummers. Bij het instellen van locale = Locale(identifier: "nl_NL") wordt firstWeekday automatisch 2 (maandag). Handmatige instelling overschrijft de waarde uit locale.

Samenvatting

  • Calendar — Foundation-klasse voor kalenderberekeningen, die Date via DateComponents verbindt met menselijk leesbare componenten.
  • 17 kalendersystemen worden ondersteund door Foundation — van Gregoriaans tot Boeddhistisch en Japans, met automatische inachtneming van regionale regels.
  • Calendar.current komt overeen met de systeemkalender van de gebruiker — gebruik het voor UI en DateFormatter.
  • Calendar.dateInterval en Calendar.range — essentiële methoden voor het werken met periodegrenzen en componentbereiken.
  • Calendar.date(byAdding:) verwerkt correct verschillende maandlengtes en schrikkeljaren — vervang het niet door TimeInterval-rekenkunde.
  • TimeZone en Locale als eigenschappen van Calendar beïnvloeden alle kalenderberekeningen — stel ze expliciet in voor voorspelbaar gedrag.
  • firstWeekday wordt bepaald door de locale en beïnvloedt weeknummers — stel het voor globale applicaties expliciet in of gebruik Calendar.current.

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