Calendar — bu taqvim tizimini belgilaydigan va taqvim hisob-kitoblari uchun metodlarni taqdim etadigan Foundation sinfidir: sana komponentlarini olish, sanalar orasidagi farqni hisoblash, davr chegaralarini topish va sanalarni siljitish. Taqvim mutlaq vaqtni (Date) inson o'qiy oladigan komponentlar bilan bog'laydi va mintaqaviy xususiyatlarni hisobga oladi: haftaning boshlanishi, vaqt mintaqasi va yozgi vaqt. Apple Developer Documentation (2025) ma'lumotlariga ko'ra, Foundation 17 ta taqvim tizimini qo'llab-quvvatlaydi — Grigoriyandan Buddist va Yapon taqvimigacha, bu esa Calendar ni xalqaro ilovalar uchun universal vositaga aylantiradi.
Asosiy ma'lumotlar
Calendar — bu ICU (International Components for Unicode) asosida taqvim hisob-kitoblarini amalga oshiradigan Foundation sinfidir. Taqvim mutlaq vaqt (Date) ning taqvim komponentlariga qanday moslashtirilishini belgilaydi: yil, oy, kun, soat, daqiqa, soniya. Calendar bo'lmasa, bugungi yil, oy va kunni aniqlab bo'lmaydi — Date o'z-o'zidan bu ma'lumotni o'z ichiga olmaydi.
Taqvim uch guruh parametrlarni hisobga oladi: taqvim tizimi (Grigorian, Buddist, Yapon), vaqt mintaqasi va lokal. Calendar.current uchalasini foydalanuvchining tizim sozlamalaridan birlashtiradi. Calendar.autoupdatingCurrent — NotificationCenter orqali ilovani qayta ishga tushirmasdan sozlamalar o'zgartirilganda avtomatik yangilanadigan maxsus versiyadir.
Taqvim Foundation da qiymat turi (value type) hisoblanadi. Calendar(identifier:) qat'iy parametrlar bilan yangi instansiya yaratadi. Taqvimni nusxalash, == orqali solishtirish va lug'atda kalit sifatida ishlatish mumkin. Bu test qilish uchun aniq timeZone va locale sozlamalari bilan taqvimlar yaratishga imkon beradi.
Calendar — Objective-C NSCalendar ning Swift versiyasi, as Calendar / as NSCalendar ko'prigi bilan. Zamonaviy Swift da hamma joyda Calendar ishlatiladi. NSCalendar Objective-C API bilan orqaga qarab muvofiqlik uchun qoladi. Calendar NS prefiksisiz to'liq metodlar to'plamiga, type-safe argumentlarga va Swift ixtiyoriyligiga ega.
Thread Safety — Calendar o'qish uchun thread-safe. Yaratilgan instansiyani bir nechta thread dan xavfsiz o'qish mumkin. Xususiyatlarni o'zgartirish (timeZone, locale) thread-safe emas — turli konfiguratsiyalar uchun alohida Calendar instansiyalarini yarating.
Foundation 17 ta taqvim tizimini Calendar.Identifier enumeratsiyasi orqali qo'llab-quvvatlaydi. Har bir tizim o'zining kabisa yillari qoidalari, oylar soni va era boshlanishiga ega. Taqvim tanlovi barcha hisob-kitoblarga ta'sir qiladi: dateComponents, dateInterval, nextDate.
Asosiy taqvim tizimlari:
Calendar(identifier: .gregorian) — eng ko'p ishlatiladigan. Xalqaro ISO 8601 standartiga mos keladi va ko'pchilik mamlakatlarda standart taqvimdir. Xalqaro auditoriyasi bo'lgan ilovalar uchun Calendar.current dan foydalaning — avtomatik ravishda foydalanuvchining tizim taqvimiga mos keladi.
| Identifikator | Tur | Foydalanish mintaqasi |
|---|---|---|
| .gregorian | Quyosh | Xalqaro |
| .buddhist | Quyosh | Tailand, Kambodja |
| .japanese | Quyosh | Yaponiya |
| .hebrew | Oy-Quyosh | Isroil |
| .islamic | Oy | Islom mamlakatlari |
| .chinese | Oy-Quyosh | Xitoy |
DateComponents va Calendar — ajralmas juftlik. Calendar.dateComponents(_:from:) taqvimning vaqt mintaqasini hisobga olgan holda Date dan komponentlarni chiqaradi. Calendar.date(from:) yetishmaydigan maydonlarni standart qiymatlar bilan to'ldirib, DateComponents dan Date yaratadi: kun = 1, soat = 0, daqiqa = 0, soniya = 0.
Calendar.component metodi bitta komponentni chiqaradi, bu tezkor tekshirish uchun qulay. Calendar.dateComponents bir chaqiruvda komponentlar to'plamini chiqaradi — bu samaraliroq, chunki Calendar taqvim hisob-kitoblarini bir marta bajaradi, har bir komponent uchun alohida emas. 3+ komponent ro'yxati uchun doimo dateComponents dan foydalaning.
Calendar.compare ikki Date ni berilgan aniqlik bilan solishtiradi. toGranularity parametri qaysi komponentgacha solishtirishni belgilaydi: .year faqat yilni, .month — yil va oyni, .day — yil, oy, kunni solishtiradi. Bu ikki sananing vaqtni hisobga olmagan holda bir kunga tegishli ekanligini tekshirish uchun qulay.
let calendar = Calendar.current
let now = Date()
// Bitta komponentni olish
let year = calendar.component(.year, from: now)
// Komponentlar to'plamini olish
let comps = calendar.dateComponents(
[.year, .month, .day], from: now
)
// Kun aniqligi bilan solishtirish
let isSameDay = calendar.compare(date1, to: date2,
toGranularity: .day) == .orderedSame
// Sana bugunligini tekshir
let isToday = calendar.isDateInToday(someDate)
Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — nisbiy tekshirishlar uchun metodlar. Calendar.isDate(_:inSameDayAs:) ikki sananing taqvim vaqt mintaqasini hisobga olgan holda bir kalendar kuniga to'g'ri kelishini tekshiradi. Bu metodlar ichki ravishda Calendar.compare dan foydalanadi va tez-tez chaqirish uchun optimallashtirilgan.
Calendar.dateInterval — analitika va UI uchun eng foydali metodlardan biri. Belgilangan komponent uchun DateInterval qaytaradi: kun, hafta, oy, yilning boshlanishi va tugashi. DateInterval start (Date) va end (Date) — davr chegaralarini o'z ichiga oladi. Masalan, dateInterval(of: .weekOfYear, for: Date()) joriy haftaning dushanba boshlanishi va yakshanba tugashini qaytaradi.
Calendar.date byAdding bilan — sanani siljitish metodi. Calendar.date(byAdding: .day, value: 7, to: Date()) bir haftadan keyingi sanani qaytaradi. Calendar.date(byAdding: DateComponents) — yanada moslashuvchan versiya, bir nechta komponentni bir vaqtning o'zida siljitish imkonini beradi: +1 oy +3 kun. Calendar avtomatik ravishda oylarning turli uzunligini va kabisa yillarini hisobga oladi.
Calendar.nextDate berilgan DateComponents ga mos keladigan keyingi sanani qidiradi. matchingPolicy parametri mos kelmaslik holatida xatti-harakatni belgilaydi: .nextTime — vaqt bo'yicha keyingi moslik, .nextTimePreservingSmallerComponents — asl sanadan daqiqa va soniyalarni saqlaydi, .strict — aniq moslikni talab qiladi.
let calendar = Calendar.current
let today = Date()
// Haftaning boshlanishi va tugashi
let weekInterval = calendar.dateInterval(
of: .weekOfYear, for: today
)!
// 1 oyga siljitish
let nextMonth = calendar.date(
byAdding: .month, value: 1, to: today
)!
// DateComponents orqali siljitish
var delta = DateComponents()
delta.month = 1
delta.day = 3
let shifted = calendar.date(byAdding: delta, to: today)!
// Keyingi 13-juma
let friday13Components = DateComponents(
weekday: 6, day: 13
)
let nextFriday13 = calendar.nextDate(
after: today, matching: friday13Components,
matchingPolicy: .nextTime
)
EnumerateDates — naqsh bo'yicha sanalarni sanash uchun kuchli metod. Calendar.enumerateDates(startingAfter:matching:matchingPolicy:using:) blok stop = true qaytarmaguncha har bir moslik uchun blokni chaqiradi. Taqvim va jadvallarda takrorlanuvchi hodisalarni yaratish uchun ishlatiladi. Metod ICU tomonidan optimallashtirilganligi sababli nextDate bilan qo'lda siklga qaraganda samaraliroq.
TimeZone — Calendar ning ajralmas qismi. Vaqt mintaqasi mutlaq Date qaysi taqvim vaqtiga mos kelishini belgilaydi. Xuddi shu Date UTC va Moskvada turlicha komponentlar beradi: Date() UTC da 10:00 ni, MSK da esa 13:00 ni ko'rsatishi mumkin. Calendar.timeZone standart bo'yicha TimeZone.current ga teng.
Locale haftaning birinchi kuniga, yilning birinchi haftasidagi minimal kunlar soniga (minDaysInFirstWeek) va oylar/hafta kunlari nomlariga (DateFormatter orqali konvertatsiyada) ta'sir qiladi. Calendar.locale standart bo'yicha Locale.current ga teng. O'zbek lokalida hafta dushanbadan boshlanadi, Amerika lokalida — yakshanbadan.
Calendar.availableIdentifiers barcha qo'llab-quvvatlanadigan taqvim identifikatorlari ro'yxatini qaytaradi. static property Calendar.availableCalendarIdentifiers — bir xil identifikatorlar bilan satrlar massivi. Taqvim tanlash UI sini qurish va qurilmada muayyan taqvim tizimining mavjudligini tekshirish uchun ishlatiladi.
// Muayyan vaqt mintaqasi bilan taqvim
var utcCalendar = Calendar(identifier: .gregorian)
utcCalendar.timeZone = TimeZone(identifier: "UTC")!
// Rus lokali bilan taqvim
var russianCalendar = Calendar(identifier: .gregorian)
russianCalendar.locale = Locale(identifier: "ru_RU")
// Birinchi hafta kuni lokalga bog'liq
let firstWeekday = russianCalendar.firstWeekday
// 2 = dushanba (uz_UZ da)
// Mavjud taqvimlar ro'yxati
for identifier in Calendar.availableIdentifiers {
print(identifier)
}
firstWeekday — haftaning qaysi kuni birinchi hisoblanishini belgilaydigan Calendar xususiyati. O'zbek lokalida Sunday = 2 (dushanba birinchi). Amerika lokalida Sunday = 1. Bu weekOfMonth va weekOfYear ishiga ta'sir qiladi: bir xil sana turli lokallarda turli hafta raqamlariga tegishli bo'lishi mumkin. Sanalar bilan ishlaydigan ilovalar uchun Calendar.current dan foydalaning yoki firstWeekday ni aniq belgilang.
Calendar imkoniyatlarini namoyish etadigan amaliy stsenariylarni ko'rib chiqaylik. Har bir misol iOS ishlab chiqishning aniq vazifasini hal qiladi va taqvim hisob-kitoblaridan to'g'ri foydalanish usulini ko'rsatadi.
Calendar.dateInterval(of: .month, for:) joriy oyning chegaralarini qaytaradi. Date ning ushbu intervalga tegishliligini tekshirish — sananing joriy oyga tegishli ekanligini aniqlashning eng tez usuli. Muqobil usul — Calendar.compare granularity .month bilan: agar natija .orderedSame bo'lsa, oy mos keladi.
func isInCurrentMonth(_ date: Date) -> Bool {
let calendar = Calendar.current
let monthInterval = calendar.dateInterval(
of: .month, for: Date()
)!
return monthInterval.contains(date)
}
// Oyda kunlar soni
func daysInMonth(for date: Date) -> Int {
let calendar = Calendar.current
return calendar.range(
of: .day, in: .month, for: date
)?.count ?? 0
}
// To'g'ri yakunlash bilan oylarni qo'shish
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:) boshqa komponent kontekstida belgilangan komponent uchun ruxsat etilgan qiymatlar oralig'ini qaytaradi. Masalan, range(of: .day, in: .month, for: date) 31 kunlik oylar uchun 1..<32, kabisa bo'lmagan yilning fevrali uchun 1..<29 qaytaradi. Bu oydagi kunlar sonini bilishning to'g'ri usuli, hardkod qiymatlardan foydalanish emas.
Oylarni qo'shish Calendar.date(byAdding:value:to:) orqali chegara sanalarni to'g'ri boshqaradi. Agar 31 yanvarga 1 oy qo'shilsa, Calendar 28 fevralni (yoki kabisa yilida 29 fevralni) qaytaradi, TimeInterval orqali oddiy 30 kun qo'shilganda 3 mart emas. Bu taqvim hisob-kitoblari uchun TimeInterval dan foydalanmaslikning yana bir sababidir.
| Calendar metodi | Vazifasi | Misol |
|---|---|---|
| dateInterval | Davr chegaralari | Oyning boshlanishi va tugashi |
| range(of:in:for:) | Komponent oralig'i | Joriy oyda kunlar |
| date(byAdding:) | Sanalarni siljitish | Bugundan +1 oy |
| isDateInToday | Bugunligini tekshirish | Sana bugunmi? |
| compare(toGranularity:) | Aniqlik bilan solishtirish | Vaqtsiz bir kun |
Tez-tez beriladigan savollar
Calendar.current foydalanuvchining tizim sozlamalaridan taqvimni qaytaradi — u Grigorian bo'lmasligi mumkin (masalan, Tailandda Buddist). Calendar(identifier: .gregorian) sozlamalardan qat'iy nazar har doim Grigorian taqvimini yaratadi. Sanalarni ko'rsatish uchun Calendar.current dan foydalaning, biznes mantig'i uchun — aniq tanlangan identifikatorni.
Bu oylarning turli uzunligi bilan bog'liq. Agar joriy sana 31 yanvar bo'lsa, 1 oy qo'shish 28 fevralni beradi, chunki fevralda 31 kun yo'q. Calendar avtomatik ravishda sanani oyning oxirgi ruxsat etilgan kuniga to'ldiradi. Aniq nazorat qilish uchun oyning birinchi kuniga o'tish uchun day: 1 bilan DateComponents dan foydalaning.
DateFormatter Calendar.current — foydalanuvchining tizim taqvimidan foydalanadi. Agar ilova sozlamalardan qat'iy nazar har doim Grigorian taqvimida sanalarni ko'rsatishi kerak bo'lsa, formatter.calendar = Calendar(identifier: .gregorian) ni belgilang. Bu barcha foydalanuvchilar uchun bir xil ko'rsatishni kafolatlaydi.
Calendar.range(of: .day, in: .year, for: date) 365 yoki 366 kun qaytaradi. Oddiyroq: Calendar.date(from: DateComponents(year: yil, month: 2, day: 29)) != nil — agar 29 fevral mavjud bo'lsa, yil kabisa yilidir. Calendar muayyan taqvim tizimi uchun qoidalarni o'zi hisobga oladi.
Ha, firstWeekday xususiyati yozish uchun mavjud. O'zgartirish weekOfMonth, weekOfYear va hafta raqamlari bilan bog'liq barcha hisob-kitoblarga ta'sir qiladi. locale = Locale(identifier: "uz_UZ") belgilanganda firstWeekday avtomatik ravishda 2 (dushanba) bo'ladi. Qo'lda belgilash locale dan qiymatni bekor qiladi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.