Calendar — mi ez, Date naptár és számítások Swiftben

Szerző: IT Sectr Megjelenés: 2026-07-12 Olvasási idő: 7 perc

Calendar — egy Foundation osztály, amely meghatározza a naptárrendszert és módszereket biztosít a naptári számításokhoz: dátumösszetevők kinyerése, dátumok közötti különbség kiszámítása, időszakhatárok keresése és dátumok eltolása. A naptár az abszolút időt (Date) ember által olvasható összetevőkhöz kapcsolja, és figyelembe veszi a regionális jellemzőket: a hét kezdetét, az időzónát és a nyári időszámítást. Az Apple Developer Documentation (2025) szerint a Foundation 17 naptárrendszert támogat — a Gergelytől a Buddhán és a Japánon át —, ami a Calendar-t univerzális eszközzé teszi a nemzetközivé tett alkalmazások számára.

Fő pontok

  • Calendar — Foundation osztály naptári számításokhoz: összetevők kinyerése, összehasonlítás és dátumeltolás.
  • Calendar.current — a felhasználó rendszernaptára, automatikusan figyelembe veszi a regionális beállításokat.
  • 17 naptárrendszer — a Foundation támogatja a Gergely-, Buddha-, Japán-, Héber-, Iszlám és más naptárakat.
  • Calendar.dateComponents kinyeri az összetevőket (év, hónap, nap) a Date-ből az időzóna figyelembevételével.
  • Calendar.dateInterval visszaadja a megadott időszak (nap, hét, hónap) kezdő és záró dátumát.

Mi az a Calendar a Foundation-ben?

Calendar — egy Foundation osztály, amely az ICU (International Components for Unicode) alapján valósítja meg a naptári számításokat. A naptár meghatározza, hogy az abszolút idő (Date) hogyan képeződik le naptári összetevőkre: év, hónap, nap, óra, perc, másodperc. Calendar nélkül nem lehet megtudni, hogy milyen év, hónap és nap van ma — a Date önmagában nem tartalmazza ezt az információt.

A naptár három paramétercsoportot vesz figyelembe: naptárrendszert (Gergely, Buddha, Japán), időzónát és lokált. A Calendar.current mindhármat a felhasználó rendszerbeállításaiból kombinálja. A Calendar.autoupdatingCurrent — egy speciális verzió, amely automatikusan frissül a beállítások megváltozásakor az alkalmazás újraindítása nélkül a NotificationCenteren keresztül.

A naptár egy értéktípus (value type) a Foundation-ben. A Calendar(identifier:) egy új példányt hoz létre rögzített paraméterekkel. A naptár másolható, összehasonlítható == segítségével, és használható kulcsként egy szótárban. Ez lehetővé teszi naptárak létrehozását konkrét timeZone és locale beállításokkal a teszteléshez.

Calendar és NSCalendar

Calendar — az Objective-C NSCalendar Swift-verziója, az as Calendar / as NSCalendar híddal. A modern Swift-ben mindenhol a Calendar-t használják. Az NSCalendar a visszafelé kompatibilitás érdekében maradt meg az Objective-C API-val. A Calendar rendelkezik a módszerek teljes készletével NS előtag nélkül, type-safe argumentumokkal és Swift opcionalitással.

Thread Safety — a Calendar olvasásra thread-safe. A létrehozott példány több szálból is biztonságosan olvasható. A tulajdonságok módosítása (timeZone, locale) nem thread-safe — különböző konfigurációkhoz hozzon létre külön Calendar példányokat.

Naptártípusok a Foundation-ben

A Foundation 17 naptárrendszert támogat a Calendar.Identifier felsoroláson keresztül. Minden rendszernek megvannak a saját szabályai a szökőévekre, a hónapok számára és az éra kezdetére. A naptár kiválasztása minden számítást befolyásol: dateComponents, dateInterval, nextDate.

Fő naptárrendszerek:

  • .gregorian — nemzetközi szabvány, 12 hónap, 365/366 nap, keresztény éra.
  • .buddhist — Buddha-naptár, Thaiföldön, Kambodzsában, Laoszban használják, éra 543 évvel megelőzi a Gergelyt.
  • .japanese — Japán naptár a császárok uralkodási korszakai szerint, 12 hónap, mint a Gergelyben.
  • .hebrew — Héber naptár, 12/13 hónap, szökőhónap Adár II.
  • .islamic — Iszlám naptár, 12 holdhónap, 354/355 nap.
  • .indian — Indiai nemzeti naptár (Saka), 12 hónap.

Calendar(identifier: .gregorian) — a leggyakrabban használt. Megfelel a nemzetközi ISO 8601 szabványnak, és a legtöbb országban ez az alapértelmezett naptár. Nemzetközi közönségű alkalmazásokhoz használja a Calendar.current-et — automatikusan megfelel a felhasználó rendszernaptárának.

AzonosítóTípusHasználati régió
.gregorianNapNemzetközi
.buddhistNapThaiföld, Kambodzsa
.japaneseNapJapán
.hebrewHold-NapIzrael
.islamicHoldIszlám országok
.chineseHold-NapKína

Calendar és DateComponents

DateComponents és Calendar — elválaszthatatlan pár. A Calendar.dateComponents(_:from:) kinyeri az összetevőket a Date-ből a naptár időzónájának figyelembevételével. A Calendar.date(from:) Date-et épít a DateComponents-ből, a hiányzó mezőket alapértékekkel kitöltve: nap = 1, óra = 0, perc = 0, másodperc = 0.

A Calendar.component metódus egy összetevőt nyer ki, ami kényelmes a gyors ellenőrzéshez. A Calendar.dateComponents egy összetevőkészletet nyer ki egy hívásban — ez hatékonyabb, mert a Calendar egyszer végzi el a naptári számításokat, nem minden összetevőre külön-külön. 3+ összetevőből álló lista esetén mindig a dateComponents-t használja.

Calendar.compare két Date-et hasonlít össze meghatározott pontossággal. A toGranularity paraméter határozza meg, hogy melyik összetevőig történjen az összehasonlítás: .year csak az évet hasonlítja össze, .month — évet és hónapot, .day — évet, hónapot, napot. Ez kényelmes annak ellenőrzésére, hogy két dátum ugyanarra a napra esik-e, az idő figyelembevétele nélkül.

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

// Egy összetevő kinyerése
let year = calendar.component(.year, from: now)

// Összetevőkészlet kinyerése
let comps = calendar.dateComponents(
    [.year, .month, .day], from: now
)

// Összehasonlítás nap pontossággal
let isSameDay = calendar.compare(date1, to: date2,
                                  toGranularity: .day) == .orderedSame

// Ellenőrizze, hogy a dátum ma van-e
let isToday = calendar.isDateInToday(someDate)

Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — relatív ellenőrzések metódusai. A Calendar.isDate(_:inSameDayAs:) ellenőrzi, hogy két dátum ugyanarra a naptári napra esik-e a naptár időzónájának figyelembevételével. Ezek a metódusok a Calendar.compare-t használják belsőleg, és gyakori hívásokra vannak optimalizálva.

Calendar számítások

Calendar.dateInterval — az egyik leghasznosabb metódus analitikához és UI-hoz. Visszaadja a DateInterval-et a megadott összetevőhöz: a nap, hét, hónap, év kezdetét és végét. A DateInterval tartalmazza a start (Date) és end (Date) értékeket — az időszak határait. Például a dateInterval(of: .weekOfYear, for: Date()) visszaadja az aktuális hét hétfő kezdetét és vasárnap végét.

Calendar.date byAdding-gal — metódus a dátum eltolásához. A Calendar.date(byAdding: .day, value: 7, to: Date()) visszaadja a dátumot egy hét múlva. A Calendar.date(byAdding: DateComponents) — rugalmasabb verzió, amely lehetővé teszi több összetevő egyidejű eltolását: +1 hónap +3 nap. A Calendar automatikusan figyelembe veszi a hónapok eltérő hosszát és a szökőéveket.

Calendar.nextDate megkeresi a következő dátumot, amely megfelel a megadott DateComponents-nek. A matchingPolicy paraméter határozza meg a viselkedést, ha nincs egyezés: .nextTime — következő egyezés időben, .nextTimePreservingSmallerComponents — megtartja a perceket és másodperceket az eredeti dátumból, .strict — pontos egyezést követel meg.

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

// A hét kezdete és vége
let weekInterval = calendar.dateInterval(
    of: .weekOfYear, for: today
)!

// Eltolás 1 hónappal
let nextMonth = calendar.date(
    byAdding: .month, value: 1, to: today
)!

// Eltolás DateComponents segítségével
var delta = DateComponents()
delta.month = 1
delta.day = 3
let shifted = calendar.date(byAdding: delta, to: today)!

// Következő péntek 13.
let friday13Components = DateComponents(
    weekday: 6, day: 13
)
let nextFriday13 = calendar.nextDate(
    after: today, matching: friday13Components,
    matchingPolicy: .nextTime
)

EnumerateDates — egy hatékony metódus a dátumok mintázat szerinti iterálásához. A Calendar.enumerateDates(startingAfter:matching:matchingPolicy:using:) egy blokkot hív meg minden egyezéshez, amíg a blokk vissza nem adja a stop = true értéket. Ismétlődő események generálására használják naptárakban és ütemezésekben. A metódus hatékonyabb, mint a manuális ciklus nextDate-tel, mert az ICU optimalizálja.

TimeZone és Locale

TimeZone — a Calendar elválaszthatatlan része. Az időzóna határozza meg, hogy az abszolút Date melyik naptári időnek felel meg. Ugyanaz a Date UTC-ben és Moszkvában különböző összetevőket ad: a Date() UTC-ben 10:00-t mutathat, MSK-ban pedig 13:00-t. A Calendar.timeZone alapértelmezés szerint egyenlő a TimeZone.current-tel.

Locale befolyásolja a hét első napját, az év első hetének minimális napszámát (minDaysInFirstWeek), valamint a hónapok/hét napjainak neveit (a DateFormatteren keresztüli konverziónál). A Calendar.locale alapértelmezés szerint egyenlő a Locale.current-tel. Magyar lokálban a hét hétfőn kezdődik, az amerikaiban — vasárnap.

Calendar.availableIdentifiers visszaadja az összes támogatott naptári azonosító listáját. static property Calendar.availableCalendarIdentifiers — sztringek tömbje ugyanezekkel az azonosítókkal. Használják naptárválasztó UI felépítéséhez és egy adott naptárrendszer elérhetőségének ellenőrzéséhez az eszközön.

swift
// Naptár meghatározott időzónával
var utcCalendar = Calendar(identifier: .gregorian)
utcCalendar.timeZone = TimeZone(identifier: "UTC")!

// Naptár orosz lokállal
var russianCalendar = Calendar(identifier: .gregorian)
russianCalendar.locale = Locale(identifier: "ru_RU")

// A hét első napja a lokáltól függ
let firstWeekday = russianCalendar.firstWeekday
// 2 = hétfő (hu_HU-ban)

// Elérhető naptárak listája
for identifier in Calendar.availableIdentifiers {
    print(identifier)
}

firstWeekday — a Calendar tulajdonsága, amely meghatározza, hogy a hét melyik napja számít elsőnek. Magyar lokálban Sunday = 2 (hétfő az első). Amerikai lokálban Sunday = 1. Ez befolyásolja a weekOfMonth és weekOfYear működését: ugyanaz a dátum különböző lokálokban különböző hét számokhoz rendelődhet. Dátumokkal dolgozó alkalmazásokhoz használja a Calendar.current-et, vagy állítsa be explicit módon a firstWeekday-t.

Példák a Calendar használatára

Tekintsük át a Calendar képességeit bemutató gyakorlati forgatókönyveket. Minden példa egy konkrét iOS-fejlesztési feladatot old meg, és megmutatja a naptári számítások helyes használatát.

Ellenőrzés: ebben a hónapban van a dátum?

Calendar.dateInterval(of: .month, for:) visszaadja az aktuális hónap határait. Annak ellenőrzése, hogy a Date ebbe az intervallumba esik-e — a leggyorsabb módja annak meghatározására, hogy a dátum az aktuális hónapba tartozik-e. Alternatív mód — Calendar.compare .month granularity-val: ha az eredmény .orderedSame, akkor a hónap egyezik.

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

// Napok száma egy hónapban
func daysInMonth(for date: Date) -> Int {
    let calendar = Calendar.current
    return calendar.range(
        of: .day, in: .month, for: date
    )?.count ?? 0
}

// Hónapok hozzáadása helyes befejezéssel
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:) visszaadja a megengedett értékek tartományát a megadott összetevőhöz egy másik összetevő kontextusában. Például a range(of: .day, in: .month, for: date) 1..<32-t ad vissza a 31 napos hónapokra vagy 1..<29-t a nem szökőév februárjára. Ez a helyes módja a hónap napjai számának megtudására, nem a hardcode-olt értékek használata.

Hónapok hozzáadása a Calendar.date(byAdding:value:to:) segítségével helyesen kezeli a határdátumokat. Ha január 31-hez hozzáadunk 1 hónapot, a Calendar február 28-át ad vissza (vagy 29-ét szökőévben), nem március 3-át, mint ahogy a 30 nap TimeInterval-on keresztüli egyszerű hozzáadásával történne. Ez egy újabb ok arra, hogy ne használjunk TimeInterval-t naptári számításokhoz.

Calendar metódusCélPélda
dateIntervalIdőszak határaiHónap kezdete és vége
range(of:in:for:)Összetevő tartományaNapok az aktuális hónapban
date(byAdding:)Dátum eltolása+1 hónap mától
isDateInTodayEllenőrzés, hogy ma van-eA dátum ma van?
compare(toGranularity:)Összehasonlítás pontossággalUgyanaz a nap idő nélkül

Gyakran Ismételt Kérdések

Mi a különbség a Calendar.current és a Calendar(identifier: .gregorian) között?

Calendar.current a felhasználó rendszerbeállításaiból adja vissza a naptárt — lehet, hogy nem Gergely-naptár (például Buddha-naptár Thaiföldön). Calendar(identifier: .gregorian) mindig Gergely-naptárt hoz létre a beállításoktól függetlenül. Dátumok megjelenítéséhez használja a Calendar.current-et, üzleti logikához — az expliciten kiválasztott azonosítót.

Miért adja vissza a Calendar.date(byAdding: .month, value: 1) néha ugyanazt a dátumot?

Ez a hónapok eltérő hosszával kapcsolatos. Ha az aktuális dátum január 31., 1 hónap hozzáadása február 28-át ad, mert februárban nincs 31 nap. A Calendar automatikusan kiegészíti a dátumot a hónap utolsó megengedett napjáig. Pontos vezérléshez használja a DateComponents-t day: 1 paraméterrel a hónap első napjára lépéshez.

Melyik naptárat használja a DateFormatter alapértelmezés szerint?

DateFormatter a Calendar.current-et használja — a felhasználó rendszernaptárát. Ha az alkalmazásnak a beállításoktól függetlenül mindig a Gergely-naptárban kell megjelenítenie a dátumokat, állítsa be a formatter.calendar = Calendar(identifier: .gregorian) értéket. Ez egységes megjelenítést garantál minden felhasználó számára.

Hogyan ellenőrizhető a Calendar segítségével, hogy egy év szökőév-e?

Calendar.range(of: .day, in: .year, for: date) 365 vagy 366 napot ad vissza. Egyszerűbben: Calendar.date(from: DateComponents(year: év, month: 2, day: 29)) != nil — ha február 29. létezik, az év szökőév. A Calendar maga veszi figyelembe az adott naptárrendszer szabályait.

Megváltoztatható a firstWeekday a Calendar létrehozása után?

Igen, a firstWeekday tulajdonság írható. A változtatás befolyásolja a weekOfMonth-ot, a weekOfYear-t és minden, a hét számokkal kapcsolatos számítást. A locale = Locale(identifier: "hu_HU") beállításakor a firstWeekday automatikusan 2 lesz (hétfő). A kézi beállítás felülírja a locale-ból származó értéket.

Összefoglalás

  • Calendar — Foundation osztály naptári számításokhoz, amely a Date-t a DateComponents-en keresztül ember által olvasható összetevőkhöz kapcsolja.
  • 17 naptárrendszer támogatott a Foundation-ben — a Gergelytől a Buddhán és Japánon át, a regionális szabályok automatikus figyelembevételével.
  • Calendar.current megfelel a felhasználó rendszernaptárának — használja UI-hoz és DateFormatter-hez.
  • Calendar.dateInterval és Calendar.range — kulcsmetódusok az időszakhatárokkal és összetevő-tartományokkal való munkához.
  • Calendar.date(byAdding:) helyesen kezeli a hónapok eltérő hosszát és a szökőéveket — ne helyettesítse TimeInterval aritmetikával.
  • TimeZone és Locale a Calendar tulajdonságaiként befolyásolják az összes naptári számítást — állítsa be őket explicit módon a kiszámítható viselkedés érdekében.
  • firstWeekday a lokál által meghatározott és befolyásolja a hét számokat — globális alkalmazásokhoz állítsa be explicit módon vagy használja a Calendar.current-et.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is