Calendar — bu, təqvim sistemini təyin edən və təqvim hesablamaları üçün metodlar təqdim edən Foundation sinifidir: tarix komponentlərinin çıxarılması, tarixlər arasındakı fərqin hesablanması, dövrlərin sərhədlərinin tapılması və tarixlərin sürüşdürülməsi. Təqvim mütləq vaxtı (Date) insan tərəfindən oxuna bilən komponentlərlə əlaqələndirir və regional xüsusiyyətləri nəzərə alır: həftənin başlanğıcı, saat qurşağı və yay vaxtı. Apple Developer Documentation (2025) məlumatına görə, Foundation 17 təqvim sistemini dəstəkləyir — Qriqorian, Buddist, Yapon və digərləri — bu da Calendar-ı beynəlmiləlləşdirilmiş tətbiqlər üçün universal alət edir.
Əsas məqamlar
Calendar — bu, ICU (International Components for Unicode) əsasında təqvim hesablamalarını həyata keçirən Foundation sinifidir. Təqvim mütləq vaxtın (Date) təqvim komponentlərinə necə uyğunlaşdırıldığını müəyyən edir: il, ay, gün, saat, dəqiqə, saniyə. Calendar olmadan bugünkü ilin, ayın və günün nə olduğunu müəyyən etmək mümkün deyil — Date özlüyündə bu məlumatı ehtiva etmir.
Təqvim üç qrup parametri nəzərə alır: təqvim sistemi (Qriqorian, Buddist, Yapon), saat qurşağı və lokal. Calendar.current hər üçünü istifadəçinin sistem parametrlərindən birləşdirir. Calendar.autoupdatingCurrent — NotificationCenter vasitəsilə tətbiqin yenidən başladılmadan parametrlər dəyişdirildikdə avtomatik yenilənən xüsusi versiyadır.
Təqvim Foundation-da dəyər tipidir (value type). Calendar(identifier:) sabit parametrlərlə yeni instansiya yaradır. Təqvimi kopyalamaq, == vasitəsilə müqayisə etmək və lüğətdə açar kimi istifadə etmək olar. Bu, test üçün konkret timeZone və locale parametrləri ilə təqvimlər yaratmağa imkan verir.
Calendar — Objective-C NSCalendar-ın Swift versiyası, as Calendar / as NSCalendar körpüsü ilə. Müasir Swift-də hər yerdə Calendar istifadə olunur. NSCalendar Objective-C API ilə geriyə uyğunluq üçün qalır. Calendar NS prefiksi olmadan tam metod dəstinə, type-safe arqumentlərə və Swift seçimliyinə malikdir.
Thread Safety — Calendar oxuma üçün thread-safe-dir. Yaradılmış instansiya bir neçə thread-dən təhlükəsiz oxuna bilər. Xüsusiyyətlərin dəyişdirilməsi (timeZone, locale) thread-safe deyil — müxtəlif konfiqurasiyalar üçün ayrıca Calendar instansiyaları yaradın.
Foundation 17 təqvim sistemini Calendar.Identifier enumu vasitəsilə dəstəkləyir. Hər bir sistemin öz uzun illər qaydaları, ayların sayı və eranın başlanğıcı var. Təqvim seçimi bütün hesablamalara təsir edir: dateComponents, dateInterval, nextDate.
Əsas təqvim sistemləri:
Calendar(identifier: .gregorian) — ən çox istifadə olunan. Beynəlxalq ISO 8601 standartına uyğundur və əksər ölkələrdə standart təqvimdir. Beynəlxalq auditoriyası olan tətbiqlər üçün Calendar.current istifadə edin — avtomatik olaraq istifadəçinin sistem təqviminə uyğunlaşır.
| İdentifikator | Tip | İstifadə regionu |
|---|---|---|
| .gregorian | Günəş | Beynəlxalq |
| .buddhist | Günəş | Tayland, Kamboca |
| .japanese | Günəş | Yaponiya |
| .hebrew | Ay-Günəş | İsrail |
| .islamic | Ay | İslam ölkələri |
| .chinese | Ay-Günəş | Çin |
DateComponents və Calendar — ayrılmaz cütlük. Calendar.dateComponents(_:from:) təqvimin saat qurşağını nəzərə alaraq Date-dən komponentləri çıxarır. Calendar.date(from:) çatışmayan sahələri standart dəyərlərlə dolduraraq DateComponents-dən Date yaradır: gün = 1, saat = 0, dəqiqə = 0, saniyə = 0.
Calendar.component metodu bir komponenti çıxarır, bu da sürətli yoxlama üçün əlverişlidir. Calendar.dateComponents bir çağırışda komponentlər dəstini çıxarır — bu daha məhsuldardır, çünki Calendar təqvim hesablamalarını bir dəfə yerinə yetirir, hər komponent üçün ayrıca deyil. 3+ komponent siyahısı üçün həmişə dateComponents istifadə edin.
Calendar.compare iki Date-i verilən dəqiqliklə müqayisə edir. toGranularity parametri hansı komponentə qədər müqayisə ediləcəyini müəyyən edir: .year yalnız ili, .month — il və ayı, .day — il, ay, günü müqayisə edir. Bu, iki tarixin vaxtı nəzərə almadan eyni günə aid olub-olmadığını yoxlamaq üçün əlverişlidir.
let calendar = Calendar.current
let now = Date()
// Bir komponentin çıxarılması
let year = calendar.component(.year, from: now)
// Komponentlər dəstinin çıxarılması
let comps = calendar.dateComponents(
[.year, .month, .day], from: now
)
// Gün dəqiqliyi ilə müqayisə
let isSameDay = calendar.compare(date1, to: date2,
toGranularity: .day) == .orderedSame
// Tarixin bugün olub-olmadığını yoxla
let isToday = calendar.isDateInToday(someDate)
Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — nisbi yoxlamalar üçün metodlar. Calendar.isDate(_:inSameDayAs:) iki tarixin təqvimin saat qurşağı nəzərə alınmaqla eyni təqvim gününə düşüb-düşmədiyini yoxlayır. Bu metodlar daxili olaraq Calendar.compare istifadə edir və tez-tez çağırış üçün optimallaşdırılıb.
Calendar.dateInterval — analitika və UI üçün ən faydalı metodlardan biridir. Göstərilən komponent üçün DateInterval qaytarır: günün, həftənin, ayın, ilin başlanğıcı və sonu. DateInterval start (Date) və end (Date) — dövrün sərhədlərini ehtiva edir. Məsələn, dateInterval(of: .weekOfYear, for: Date()) cari həftənin bazar ertəsinin başlanğıcını və bazar gününün sonunu qaytarır.
Calendar.date byAdding ilə — tarixin sürüşdürülməsi metodu. Calendar.date(byAdding: .day, value: 7, to: Date()) bir həftə sonrakı tarixi qaytarır. Calendar.date(byAdding: DateComponents) — daha çevik versiya, bir neçə komponenti eyni anda sürüşdürməyə imkan verir: +1 ay +3 gün. Calendar avtomatik olaraq ayların müxtəlif uzunluğunu və uzun illəri nəzərə alır.
Calendar.nextDate verilən DateComponents-ə uyğun gələn növbəti tarixi axtarır. matchingPolicy parametri uyğunsuzluq halında davranışı müəyyən edir: .nextTime — vaxta görə növbəti uyğunluq, .nextTimePreservingSmallerComponents — orijinal tarixdən dəqiqə və saniyələri qoruyur, .strict — dəqiq uyğunluq tələb edir.
let calendar = Calendar.current
let today = Date()
// Həftənin başlanğıcı və sonu
let weekInterval = calendar.dateInterval(
of: .weekOfYear, for: today
)!
// 1 aylıq sürüşdürmə
let nextMonth = calendar.date(
byAdding: .month, value: 1, to: today
)!
// DateComponents ilə sürüşdürmə
var delta = DateComponents()
delta.month = 1
delta.day = 3
let shifted = calendar.date(byAdding: delta, to: today)!
// Növbəti cümə 13-ü
let friday13Components = DateComponents(
weekday: 6, day: 13
)
let nextFriday13 = calendar.nextDate(
after: today, matching: friday13Components,
matchingPolicy: .nextTime
)
EnumerateDates — nümunə üzrə tarixləri sıralamaq üçün güclü metod. Calendar.enumerateDates(startingAfter:matching:matchingPolicy:using:) blok stop = true qaytarana qədər hər uyğunluq üçün bloku çağırır. Təqvim və cədvəllərdə təkrarlanan hadisələrin yaradılması üçün istifadə olunur. Metod ICU tərəfindən optimallaşdırıldığı üçün nextDate ilə manual döngüdən daha səmərəlidir.
TimeZone — Calendar-ın ayrılmaz hissəsidir. Saat qurşağı mütləq Date-in hansı təqvim vaxtına uyğun olduğunu müəyyən edir. Eyni Date UTC-də və Moskvada fərqli komponentlər verir: Date() UTC-də 10:00, MSK-da isə 13:00 göstərə bilər. Calendar.timeZone standart olaraq TimeZone.current-ə bərabərdir.
Locale həftənin ilk gününə, ilin ilk həftəsindəki minimum gün sayına (minDaysInFirstWeek) və ayların/həftə günlərinin adlarına (DateFormatter vasitəsilə çevrilmədə) təsir edir. Calendar.locale standart olaraq Locale.current-ə bərabərdir. Azərbaycan lokalında həftə bazar ertəsindən başlayır, Amerika lokalında — bazar günündən.
Calendar.availableIdentifiers bütün dəstəklənən təqvim identifikatorlarının siyahısını qaytarır. static property Calendar.availableCalendarIdentifiers — eyni identifikatorlarla sətir massivi. Təqvim seçimi UI-nin qurulması və cihazda konkret təqvim sisteminin mövcudluğunun yoxlanılması üçün istifadə olunur.
// Müəyyən saat qurşağı ilə təqvim
var utcCalendar = Calendar(identifier: .gregorian)
utcCalendar.timeZone = TimeZone(identifier: "UTC")!
// Rus lokalı ilə təqvim
var russianCalendar = Calendar(identifier: .gregorian)
russianCalendar.locale = Locale(identifier: "ru_RU")
// İlk həftə günü lokaldan asılıdır
let firstWeekday = russianCalendar.firstWeekday
// 2 = bazar ertəsi (az_AZ-də)
// Mövcud təqvimlərin siyahısı
for identifier in Calendar.availableIdentifiers {
print(identifier)
}
firstWeekday — həftənin hansı gününün birinci hesab edildiyini təyin edən Calendar xüsusiyyəti. Azərbaycan lokalında Sunday = 2 (bazar ertəsi birinci). Amerika lokalında Sunday = 1. Bu, weekOfMonth və weekOfYear-in işinə təsir edir: eyni tarix müxtəlif lokallarda fərqli həftə nömrələrinə aid edilə bilər. Tarixlərlə işləyən tətbiqlər üçün Calendar.current istifadə edin və ya firstWeekday-i açıq şəkildə təyin edin.
Calendar-ın imkanlarını nümayiş etdirən praktik ssenariləri nəzərdən keçirək. Hər bir nümunə iOS inkişafının konkret tapşırığını həll edir və təqvim hesablamalarından düzgün istifadə yolunu göstərir.
Calendar.dateInterval(of: .month, for:) cari ayın sərhədlərini qaytarır. Date-in bu intervala daxil olmasının yoxlanılması — tarixin cari aya aid olub-olmadığını müəyyən etməyin ən sürətli yoludur. Alternativ üsul — Calendar.compare granularity .month ilə: nəticə .orderedSame olarsa, ay uyğun gəlir.
func isInCurrentMonth(_ date: Date) -> Bool {
let calendar = Calendar.current
let monthInterval = calendar.dateInterval(
of: .month, for: Date()
)!
return monthInterval.contains(date)
}
// Ayda günlərin sayı
func daysInMonth(for date: Date) -> Int {
let calendar = Calendar.current
return calendar.range(
of: .day, in: .month, for: date
)?.count ?? 0
}
// Düzgün tamamlama ilə ayların əlavə edilməsi
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:) başqa bir komponentin kontekstində göstərilən komponent üçün icazə verilən dəyərlər diapazonunu qaytarır. Məsələn, range(of: .day, in: .month, for: date) 31 günlü aylar üçün 1..<32, uzun olmayan ilin fevralı üçün 1..<29 qaytarır. Bu, aydakı günlərin sayını öyrənməyin düzgün yoludur, hardkod dəyərlərdən istifadə etmək yox.
Ayların əlavə edilməsi Calendar.date(byAdding:value:to:) vasitəsilə sərhəd tarixləri düzgün idarə edir. 31 yanvara 1 ay əlavə edilərsə, Calendar 28 fevral (və ya uzun ildə 29 fevral) qaytarır, TimeInterval vasitəsilə sadə 30 gün əlavə edildikdə olduğu kimi 3 mart yox. Bu, təqvim hesablamaları üçün TimeInterval-dən istifadə etməməyin daha bir səbəbidir.
| Calendar metodu | Təyinat | Nümunə |
|---|---|---|
| dateInterval | Dövr sərhədləri | Ayın başlanğıcı və sonu |
| range(of:in:for:) | Komponent diapazonu | Cari ayda günlər |
| date(byAdding:) | Tarixin sürüşdürülməsi | Bugündən +1 ay |
| isDateInToday | Bugün yoxlaması | Tarix bugündür? |
| compare(toGranularity:) | Dəqiqliklə müqayisə | Vaxtsız eyni gün |
Tez-tez verilən suallar
Calendar.current istifadəçinin sistem parametrlərindən təqvimi qaytarır — o, Qriqorian olmaya bilər (məsələn, Taylandda Buddist). Calendar(identifier: .gregorian) parametrlərdən asılı olmayaraq həmişə Qriqorian təqvimi yaradır. Tarixləri göstərmək üçün Calendar.current istifadə edin, biznes məntiqi üçün — açıq şəkildə seçilmiş identifikator.
Bu, ayların müxtəlif uzunluğu ilə bağlıdır. Əgər cari tarix 31 yanvardırsa, 1 ay əlavə etmək 28 fevral verir, çünki fevralda 31 gün yoxdur. Calendar avtomatik olaraq tarixi ayın son icazə verilən gününə qədər tamamlayır. Dəqiq nəzarət üçün ayın ilk gününə keçmək üçün day: 1 ilə DateComponents istifadə edin.
DateFormatter Calendar.current — istifadəçinin sistem təqvimindən istifadə edir. Tətbiq parametrlərdən asılı olmayaraq həmişə Qriqorian təqvimində tarixləri göstərməlidirsə, formatter.calendar = Calendar(identifier: .gregorian) təyin edin. Bu, bütün istifadəçilər üçün vahid göstərməni təmin edir.
Calendar.range(of: .day, in: .year, for: date) 365 və ya 366 gün qaytarır. Daha sadə: Calendar.date(from: DateComponents(year: il, month: 2, day: 29)) != nil — əgər 29 fevral mövcuddursa, il uzun ildir. Calendar konkret təqvim sistemi üçün qaydaları özü nəzərə alır.
Bəli, firstWeekday xüsusiyyəti yazmaq üçün əlçatandır. Dəyişiklik weekOfMonth, weekOfYear və həftə nömrələri ilə bağlı bütün hesablamalara təsir edir. locale = Locale(identifier: "az_AZ") təyin edildikdə firstWeekday avtomatik olaraq 2 (bazar ertəsi) olur. Əl ilə təyin etmək locale-dən dəyəri ləğv edir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun