Calendar — ano ito, kalendaryo ng Date at mga kalkulasyon sa Swift

May-akda: IT Sectr Nai-publish: 2026-07-12 Oras ng pagbabasa: 7 min

Calendar — ay isang klase ng Foundation na tumutukoy sa sistema ng kalendaryo at nagbibigay ng mga pamamaraan para sa mga kalkulasyon ng kalendaryo: pagkuha ng mga bahagi ng petsa, pagkalkula ng pagkakaiba sa pagitan ng mga petsa, paghahanap ng mga hangganan ng panahon, at paglipat ng mga petsa. Ang kalendaryo ay nag-uugnay ng absolute na oras (Date) sa mga bahaging nababasa ng tao at isinasaalang-alang ang mga rehiyonal na katangian: simula ng linggo, time zone, at daylight saving time. Ayon sa Apple Developer Documentation (2025), sinusuportahan ng Foundation ang 17 sistema ng kalendaryo — mula Gregorian hanggang Buddhist at Japanese, na ginagawang unibersal na kasangkapan ang Calendar para sa mga internasyonalisadong aplikasyon.

Mga Pangunahing Punto

  • Calendar — klase ng Foundation para sa mga kalkulasyon ng kalendaryo: pagkuha ng mga bahagi, paghahambing, at paglipat ng mga petsa.
  • Calendar.current — kalendaryo ng system ng gumagamit, awtomatikong isinasaalang-alang ang mga rehiyonal na setting.
  • 17 sistema ng kalendaryo — sinusuportahan ng Foundation ang Gregorian, Buddhist, Japanese, Hebrew, Islamic, at iba pa.
  • Calendar.dateComponents kumukuha ng mga bahagi (taon, buwan, araw) mula sa Date na isinasaalang-alang ang time zone.
  • Calendar.dateInterval nagbabalik ng simula at wakas na petsa ng tinukoy na panahon (araw, linggo, buwan).

Ano ang Calendar sa Foundation?

Calendar — ay isang klase ng Foundation na nagpapatupad ng mga kalkulasyon ng kalendaryo batay sa ICU (International Components for Unicode). Tinutukoy ng kalendaryo kung paano imamapa ang absolute na oras (Date) sa mga bahagi ng kalendaryo: taon, buwan, araw, oras, minuto, segundo. Kung walang Calendar, hindi malalaman kung anong taon, buwan, at araw ngayon — ang Date mismo ay hindi naglalaman ng impormasyong ito.

Isinasaalang-alang ng kalendaryo ang tatlong grupo ng mga parameter: sistema ng kalendaryo (Gregorian, Buddhist, Japanese), time zone, at lokal. Pinagsasama ng Calendar.current ang lahat ng tatlo mula sa mga setting ng system ng gumagamit. Ang Calendar.autoupdatingCurrent — espesyal na bersyon na awtomatikong ina-update kapag nagbago ang mga setting nang hindi nire-restart ang application sa pamamagitan ng NotificationCenter.

Ang kalendaryo ay isang value type sa Foundation. Lumilikha ang Calendar(identifier:) ng bagong instance na may nakapirming mga parameter. Ang kalendaryo ay maaaring kopyahin, ihambing sa pamamagitan ng ==, at gamitin bilang susi sa diksyunaryo. Pinapayagan nito ang paglikha ng mga kalendaryo na may tiyak na mga setting ng timeZone at locale para sa pagsubok.

Calendar at NSCalendar

Calendar — bersyon ng Swift ng NSCalendar ng Objective-C, na may tulay na as Calendar / as NSCalendar. Sa modernong Swift, ginagamit ang Calendar sa lahat ng dako. Nananatili ang NSCalendar para sa backward compatibility sa Objective-C API. Ang Calendar ay may kumpletong hanay ng mga pamamaraan nang walang NS prefix, na may type-safe na argumento at Swift optionality.

Thread Safety — ang Calendar ay thread-safe para sa pagbabasa. Ang nilikhang instance ay maaaring ligtas na basahin mula sa maraming thread. Ang pagbabago ng mga property (timeZone, locale) ay hindi thread-safe — para sa iba't ibang configuration, lumikha ng hiwalay na mga instance ng Calendar.

Mga Uri ng Kalendaryo sa Foundation

Sinusuportahan ng Foundation ang 17 sistema ng kalendaryo sa pamamagitan ng enumeration na Calendar.Identifier. Bawat sistema ay may sariling mga patakaran para sa leap year, bilang ng mga buwan, at simula ng panahon. Ang pagpili ng kalendaryo ay nakakaapekto sa lahat ng kalkulasyon: dateComponents, dateInterval, nextDate.

Mga pangunahing sistema ng kalendaryo:

  • .gregorian — internasyonal na pamantayan, 12 buwan, 365/366 araw, panahon ng Kristiyano.
  • .buddhist — kalendaryong Buddhist, ginagamit sa Thailand, Cambodia, Laos, panahon ay 543 taon nauuna sa Gregorian.
  • .japanese — kalendaryong Hapon ayon sa mga panahon ng paghahari ng emperador, 12 buwan tulad ng Gregorian.
  • .hebrew — kalendaryong Hebrew, 12/13 buwan, leap month na Adar II.
  • .islamic — kalendaryong Islamiko, 12 buwang lunar, 354/355 araw.
  • .indian — pambansang kalendaryo ng India (Saka), 12 buwan.

Calendar(identifier: .gregorian) — pinakamadalas gamitin. Ito ay tumutugma sa internasyonal na pamantayang ISO 8601 at ang default na kalendaryo sa karamihan ng mga bansa. Para sa mga application na may internasyonal na madla, gamitin ang Calendar.current — awtomatiko itong tumutugma sa kalendaryo ng system ng gumagamit.

TagatukoyUriRehiyon ng Paggamit
.gregorianArawInternasyonal
.buddhistArawThailand, Cambodia
.japaneseArawHapon
.hebrewLunar-ArawIsrael
.islamicLunarMga bansang Islamiko
.chineseLunar-ArawTsina

Calendar at DateComponents

DateComponents at Calendar — hindi mapaghihiwalay na pares. Kinukuha ng Calendar.dateComponents(_:from:) ang mga bahagi mula sa Date na isinasaalang-alang ang time zone ng kalendaryo. Binubuo ng Calendar.date(from:) ang Date mula sa DateComponents, pinupuno ang mga nawawalang field ng mga default na halaga: araw = 1, oras = 0, minuto = 0, segundo = 0.

Ang pamamaraang Calendar.component ay kumukuha ng isang bahagi, na maginhawa para sa mabilisang pagsusuri. Ang Calendar.dateComponents ay kumukuha ng isang set ng mga bahagi sa isang tawag — ito ay mas episyente dahil ang Calendar ay nagsasagawa ng mga kalkulasyon ng kalendaryo nang isang beses, hindi para sa bawat bahagi nang hiwalay. Para sa listahan ng 3+ bahagi, laging gamitin ang dateComponents.

Calendar.compare ay naghahambing ng dalawang Date na may tinukoy na presisyon. Tinutukoy ng parameter na toGranularity kung hanggang saang bahagi isasagawa ang paghahambing: .year ay naghahambing lamang ng taon, .month — taon at buwan, .day — taon, buwan, araw. Ito ay maginhawa para sa pagsuri kung ang dalawang petsa ay kabilang sa parehong araw, nang hindi isinasaalang-alang ang oras.

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

// Pagkuha ng isang bahagi
let year = calendar.component(.year, from: now)

// Pagkuha ng isang set ng mga bahagi
let comps = calendar.dateComponents(
    [.year, .month, .day], from: now
)

// Paghahambing na may presisyon ng araw
let isSameDay = calendar.compare(date1, to: date2,
                                  toGranularity: .day) == .orderedSame

// Suriin kung ang petsa ay ngayon
let isToday = calendar.isDateInToday(someDate)

Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — mga pamamaraan para sa relatibong pagsusuri. Ang Calendar.isDate(_:inSameDayAs:) ay sumusuri kung ang dalawang petsa ay nasa parehong araw ng kalendaryo na isinasaalang-alang ang time zone ng kalendaryo. Ang mga pamamaraang ito ay gumagamit ng Calendar.compare sa loob at optimisado para sa madalas na tawag.

Mga Kalkulasyon ng Calendar

Calendar.dateInterval — isa sa mga pinakakapaki-pakinabang na pamamaraan para sa analytics at UI. Nagbabalik ito ng DateInterval para sa tinukoy na bahagi: simula at wakas ng araw, linggo, buwan, taon. Naglalaman ang DateInterval ng start (Date) at end (Date) — mga hangganan ng panahon. Halimbawa, ang dateInterval(of: .weekOfYear, for: Date()) ay nagbabalik ng simula ng Lunes at wakas ng Linggo ng kasalukuyang linggo.

Calendar.date na may byAdding — pamamaraan para sa paglipat ng petsa. Ang Calendar.date(byAdding: .day, value: 7, to: Date()) ay nagbabalik ng petsa makalipas ang isang linggo. Ang Calendar.date(byAdding: DateComponents) — mas nababaluktot na bersyon, na nagpapahintulot ng paglipat ng maraming bahagi nang sabay: +1 buwan +3 araw. Awtomatikong isinasaalang-alang ng Calendar ang iba't ibang haba ng mga buwan at leap year.

Calendar.nextDate ay naghahanap ng susunod na petsa na tumutugma sa tinukoy na DateComponents. Tinutukoy ng parameter na matchingPolicy ang pag-uugali kapag hindi tugma: .nextTime — susunod na tugma sa oras, .nextTimePreservingSmallerComponents — pinapanatili ang mga minuto at segundo mula sa orihinal na petsa, .strict — nangangailangan ng eksaktong tugma.

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

// Simula at wakas ng linggo
let weekInterval = calendar.dateInterval(
    of: .weekOfYear, for: today
)!

// Paglipat ng 1 buwan
let nextMonth = calendar.date(
    byAdding: .month, value: 1, to: today
)!

// Paglipat sa pamamagitan ng DateComponents
var delta = DateComponents()
delta.month = 1
delta.day = 3
let shifted = calendar.date(byAdding: delta, to: today)!

// Susunod na Biyernes ika-13
let friday13Components = DateComponents(
    weekday: 6, day: 13
)
let nextFriday13 = calendar.nextDate(
    after: today, matching: friday13Components,
    matchingPolicy: .nextTime
)

EnumerateDates — isang makapangyarihang pamamaraan para sa pag-ulit ng mga petsa ayon sa pattern. Ang Calendar.enumerateDates(startingAfter:matching:matchingPolicy:using:) ay tumatawag ng block para sa bawat tugma hanggang ang block ay magbalik ng stop = true. Ginagamit para sa pagbuo ng mga umuulit na kaganapan sa mga kalendaryo at iskedyul. Ang pamamaraan ay mas episyente kaysa sa manu-manong loop na may nextDate dahil ito ay optimisado ng ICU.

TimeZone at Locale

TimeZone — hindi mapaghihiwalay na bahagi ng Calendar. Tinutukoy ng time zone kung anong oras ng kalendaryo ang katumbas ng absolute na Date. Ang parehong Date sa UTC at sa Moscow ay nagbibigay ng magkaibang mga bahagi: ang Date() sa UTC ay maaaring magpakita ng 10:00, at sa MSK — 13:00. Ang Calendar.timeZone ay default na katumbas ng TimeZone.current.

Locale ay nakakaapekto sa unang araw ng linggo, pinakamababang bilang ng mga araw sa unang linggo ng taon (minDaysInFirstWeek), at mga pangalan ng buwan/araw ng linggo (sa conversion sa pamamagitan ng DateFormatter). Ang Calendar.locale ay default na katumbas ng Locale.current. Sa lokal na Pilipino, ang linggo ay nagsisimula sa Lunes, sa Amerikanong lokal — sa Linggo.

Calendar.availableIdentifiers ay nagbabalik ng listahan ng lahat ng sinusuportahang tagatukoy ng kalendaryo. static property Calendar.availableCalendarIdentifiers — array ng mga string na may parehong mga tagatukoy. Ginagamit para sa pagbuo ng UI ng pagpili ng kalendaryo at para sa pagsuri ng pagkakaroon ng isang partikular na sistema ng kalendaryo sa device.

swift
// Kalendaryo na may tiyak na time zone
var utcCalendar = Calendar(identifier: .gregorian)
utcCalendar.timeZone = TimeZone(identifier: "UTC")!

// Kalendaryo na may lokal na Ruso
var russianCalendar = Calendar(identifier: .gregorian)
russianCalendar.locale = Locale(identifier: "ru_RU")

// Unang araw ng linggo ay depende sa lokal
let firstWeekday = russianCalendar.firstWeekday
// 2 = Lunes (sa fil_PH)

// Listahan ng mga magagamit na kalendaryo
for identifier in Calendar.availableIdentifiers {
    print(identifier)
}

firstWeekday — property ng Calendar na tumutukoy kung aling araw ng linggo ang itinuturing na una. Sa lokal na Pilipino, Sunday = 2 (Lunes ang una). Sa Amerikanong lokal, Sunday = 1. Ito ay nakakaapekto sa paggana ng weekOfMonth at weekOfYear: ang parehong petsa ay maaaring italaga sa magkaibang numero ng linggo sa magkaibang lokal. Para sa mga application na may mga petsa, gamitin ang Calendar.current o tahasang itakda ang firstWeekday.

Mga Halimbawa ng Paggawa gamit ang Calendar

Tingnan natin ang mga praktikal na senaryo na nagpapakita ng mga kakayahan ng Calendar. Bawat halimbawa ay lumulutas ng isang tiyak na gawain sa pag-develop ng iOS at nagpapakita ng tamang paraan ng paggamit ng mga kalkulasyon ng kalendaryo.

Pagsusuri: ang petsa ba ay sa buwang ito?

Calendar.dateInterval(of: .month, for:) ay nagbabalik ng mga hangganan ng kasalukuyang buwan. Ang pagsusuri kung ang Date ay nasa loob ng interval na ito — ang pinakamabilis na paraan upang matukoy kung ang petsa ay kabilang sa kasalukuyang buwan. Alternatibong paraan — Calendar.compare na may granularity .month: kung ang resulta ay .orderedSame, ang buwan ay tugma.

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

// Bilang ng mga araw sa isang buwan
func daysInMonth(for date: Date) -> Int {
    let calendar = Calendar.current
    return calendar.range(
        of: .day, in: .month, for: date
    )?.count ?? 0
}

// Pagdaragdag ng mga buwan na may tamang pagkumpleto
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:) ay nagbabalik ng saklaw ng mga pinapayagang halaga para sa tinukoy na bahagi sa konteksto ng isa pang bahagi. Halimbawa, ang range(of: .day, in: .month, for: date) ay nagbabalik ng 1..<32 para sa mga buwan na may 31 araw o 1..<29 para sa Pebrero ng hindi leap year. Ito ang tamang paraan upang malaman ang bilang ng mga araw sa isang buwan, hindi ang paggamit ng hardcode na mga halaga.

Pagdaragdag ng mga buwan sa pamamagitan ng Calendar.date(byAdding:value:to:) ay wastong humahawak ng mga petsang nasa hangganan. Kung ang ika-31 ng Enero ay dagdagan ng 1 buwan, ang Calendar ay nagbabalik ng ika-28 ng Pebrero (o 29 sa leap year), hindi ika-3 ng Marso, tulad ng mangyayari sa simpleng pagdaragdag ng 30 araw sa pamamagitan ng TimeInterval. Ito ay isa pang dahilan upang hindi gumamit ng TimeInterval para sa mga kalkulasyon ng kalendaryo.

Pamamaraan ng CalendarLayuninHalimbawa
dateIntervalMga hangganan ng panahonSimula at wakas ng buwan
range(of:in:for:)Saklaw ng bahagiMga araw sa kasalukuyang buwan
date(byAdding:)Paglipat ng petsa+1 buwan mula ngayon
isDateInTodayPagsusuri kung ngayonAng petsa ba ay ngayon
compare(toGranularity:)Paghahambing na may presisyonParehong araw walang oras

Mga Madalas Itanong

Ano ang pagkakaiba sa pagitan ng Calendar.current at Calendar(identifier: .gregorian)?

Calendar.current ay nagbabalik ng kalendaryo mula sa mga setting ng system ng gumagamit — maaaring hindi ito Gregorian (halimbawa, Buddhist sa Thailand). Calendar(identifier: .gregorian) ay laging lumilikha ng Gregorian na kalendaryo anuman ang mga setting. Para sa pagpapakita ng mga petsa, gamitin ang Calendar.current, para sa lohika ng negosyo — ang tahasang piniling tagatukoy.

Bakit ang Calendar.date(byAdding: .month, value: 1) minsan ay nagbabalik ng parehong petsa?

Ito ay may kaugnayan sa iba't ibang haba ng mga buwan. Kung ang kasalukuyang petsa ay ika-31 ng Enero, ang pagdaragdag ng 1 buwan ay nagbibigay ng ika-28 ng Pebrero, dahil ang Pebrero ay walang 31 araw. Awtomatikong kinukumpleto ng Calendar ang petsa hanggang sa huling pinapayagang araw ng buwan. Para sa tumpak na kontrol, gamitin ang DateComponents na may day: 1 upang pumunta sa unang araw ng buwan.

Anong kalendaryo ang ginagamit ng DateFormatter bilang default?

DateFormatter ay gumagamit ng Calendar.current — kalendaryo ng system ng gumagamit. Kung ang application ay dapat palaging magpakita ng mga petsa sa Gregorian na kalendaryo anuman ang mga setting, itakda ang formatter.calendar = Calendar(identifier: .gregorian). Ito ay ginagarantiyahan ang pare-parehong pagpapakita para sa lahat ng gumagamit.

Paano suriin kung ang taon ay leap year sa pamamagitan ng Calendar?

Calendar.range(of: .day, in: .year, for: date) ay nagbabalik ng 365 o 366 araw. Mas simple: Calendar.date(from: DateComponents(year: taon, month: 2, day: 29)) != nil — kung ang ika-29 ng Pebrero ay umiiral, ang taon ay leap year. Ang Calendar mismo ay isinasaalang-alang ang mga patakaran para sa partikular na sistema ng kalendaryo.

Maaari bang baguhin ang firstWeekday pagkatapos gawin ang Calendar?

Oo, ang property na firstWeekday ay maaaring isulat. Ang pagbabago ay nakakaapekto sa weekOfMonth, weekOfYear, at lahat ng kalkulasyon na may kaugnayan sa mga numero ng linggo. Kapag itinakda ang locale = Locale(identifier: "fil_PH"), ang firstWeekday ay awtomatikong nagiging 2 (Lunes). Ang manu-manong setting ay nag-o-override sa halaga mula sa locale.

Buod

  • Calendar — klase ng Foundation para sa mga kalkulasyon ng kalendaryo, na nag-uugnay ng Date sa mga bahaging nababasa ng tao sa pamamagitan ng DateComponents.
  • 17 sistema ng kalendaryo ay sinusuportahan ng Foundation — mula Gregorian hanggang Buddhist at Japanese, na may awtomatikong pagsasaalang-alang ng mga rehiyonal na patakaran.
  • Calendar.current ay tumutugma sa kalendaryo ng system ng gumagamit — gamitin ito para sa UI at DateFormatter.
  • Calendar.dateInterval at Calendar.range — mga pangunahing pamamaraan para sa pagtatrabaho sa mga hangganan ng panahon at saklaw ng mga bahagi.
  • Calendar.date(byAdding:) ay wastong humahawak ng iba't ibang haba ng mga buwan at leap year — huwag itong palitan ng TimeInterval arithmetic.
  • TimeZone at Locale bilang mga property ng Calendar ay nakakaapekto sa lahat ng kalkulasyon ng kalendaryo — itakda ang mga ito nang tahasan para sa predictable na pag-uugali.
  • firstWeekday ay tinutukoy ng lokal at nakakaapekto sa mga numero ng linggo — para sa pandaigdigang application, itakda ito nang tahasan o gamitin ang Calendar.current.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din