Calendar ایک Foundation کلاس ہے جو کیلنڈر سسٹم کی وضاحت کرتی ہے اور کیلنڈر حسابات کے لیے طریقے فراہم کرتی ہے: تاریخ کے اجزاء نکالنا، تاریخوں کے درمیان فرق کا حساب لگانا، مدت کی حدود تلاش کرنا اور تاریخوں کو منتقل کرنا۔ کیلنڈر مطلق وقت (Date) کو انسانی پڑھنے کے قابل اجزاء سے جوڑتا ہے اور علاقائی خصوصیات کو مدنظر رکھتا ہے: ہفتے کا آغاز، ٹائم زون اور گرمیوں کا وقت۔ Apple Developer Documentation (2025) کے مطابق، Foundation 17 کیلنڈر سسٹمز کو سپورٹ کرتا ہے — گریگورین سے لے کر بدھ اور جاپانی تک، جو Calendar کو بین الاقوامی ایپلی کیشنز کے لیے ایک عالمگیر ٹول بناتا ہے۔
اہم نکات
Calendar ایک Foundation کلاس ہے جو ICU (International Components for Unicode) پر مبنی کیلنڈر حسابات کو نافذ کرتی ہے۔ کیلنڈر وضاحت کرتا ہے کہ مطلق وقت (Date) کیلنڈر کے اجزاء پر کیسے میپ ہوتا ہے: سال، مہینہ، دن، گھنٹہ، منٹ، سیکنڈ۔ Calendar کے بغیر یہ جاننا ناممکن ہے کہ آج کون سا سال، مہینہ اور دن ہے — Date خود میں یہ معلومات نہیں ہوتی۔
کیلنڈر تین گروپوں کے پیرامیٹرز کو مدنظر رکھتا ہے: کیلنڈر سسٹم (گریگورین، بدھ، جاپانی)، ٹائم زون اور علاقائی ترتیبات۔ Calendar.current صارف کی سسٹم ترتیبات سے تینوں کو یکجا کرتا ہے۔ Calendar.autoupdatingCurrent ایک خاص ورژن ہے جو NotificationCenter کے ذریعے ایپلیکیشن کو دوبارہ شروع کیے بغیر ترتیبات تبدیل ہونے پر خود بخود اپ ڈیٹ ہوتا ہے۔
Calendar Foundation میں ایک ویلیو ٹائپ (value type) ہے۔ Calendar(identifier:) مقررہ پیرامیٹرز کے ساتھ ایک نیا انسٹنس بناتا ہے۔ Calendar کو کاپی کیا جا سکتا ہے، == کے ذریعے موازنہ کیا جا سکتا ہے اور ڈکشنری میں کلید کے طور پر استعمال کیا جا سکتا ہے۔ یہ جانچ کے لیے مخصوص timeZone اور locale ترتیبات کے ساتھ کیلنڈر بنانے کی اجازت دیتا ہے۔
Calendar Objective-C کے NSCalendar کا Swift ورژن ہے، جو as Calendar / as NSCalendar کے ذریعے برج کیا گیا ہے۔ جدید Swift میں Calendar ہر جگہ استعمال ہوتا ہے۔ NSCalendar Objective-C APIs کے ساتھ پسماندہ مطابقت کے لیے باقی ہے۔ Calendar کے پاس NS سابقہ کے بغیر طریقوں کا مکمل سیٹ ہے، type-safe آرگیومینٹس اور Swift آپشنلٹی کے ساتھ۔
تھریڈ سیفٹی — Calendar پڑھنے کے لیے تھریڈ-محفوظ ہے۔ بنایا گیا انسٹنس متعدد تھریڈز سے محفوظ طریقے سے پڑھا جا سکتا ہے۔ خصوصیات (timeZone, locale) میں تبدیلی تھریڈ-محفوظ نہیں ہے — مختلف کنفیگریشنز کے لیے علیحدہ Calendar انسٹنسز بنائیں۔
Foundation Calendar.Identifier انومریشن کے ذریعے 17 کیلنڈر سسٹمز کو سپورٹ کرتا ہے۔ ہر سسٹم کے لیپ ایئر، مہینوں کی تعداد اور دور کے آغاز کے لیے اپنے قواعد ہیں۔ کیلنڈر کا انتخاب تمام حسابات کو متاثر کرتا ہے: dateComponents، dateInterval، nextDate۔
اہم کیلنڈر سسٹم:
Calendar(identifier: .gregorian) — سب سے زیادہ استعمال ہوتا ہے۔ یہ بین الاقوامی معیار ISO 8601 کے مطابق ہے اور زیادہ تر ممالک میں ڈیفالٹ کیلنڈر ہے۔ بین الاقوامی سامعین والی ایپلیکیشنز کے لیے Calendar.current استعمال کریں — یہ خود بخود صارف کے سسٹم کیلنڈر سے میل کھاتا ہے۔
| شناخت کنندہ | قسم | استعمال کا علاقہ |
|---|---|---|
| .gregorian | شمسی | بین الاقوامی |
| .buddhist | شمسی | تھائی لینڈ، کمبوڈیا |
| .japanese | شمسی | جاپان |
| .hebrew | قمری-شمسی | اسرائیل |
| .islamic | قمری | اسلامی ممالک |
| .chinese | قمری-شمسی | چین |
DateComponents اور Calendar ایک لازم و ملزوم جوڑی ہیں۔ Calendar.dateComponents(_:from:) کیلنڈر کے ٹائم زون کا احترام کرتے ہوئے Date سے اجزاء نکالتا ہے۔ Calendar.date(from:) DateComponents سے Date جمع کرتا ہے، غائب فیلڈز کو ڈیفالٹ ویلیوز سے بھرتا ہے: دن = 1، گھنٹہ = 0، منٹ = 0، سیکنڈ = 0۔
Calendar.component طریقہ ایک واحد جزو نکالتا ہے، فوری جانچ کے لیے آسان ہے۔ Calendar.dateComponents ایک کال میں متعدد اجزاء نکالتا ہے — یہ زیادہ موثر ہے کیونکہ Calendar ہر جزو کے لیے الگ الگ کرنے کی بجائے ایک بار کیلنڈر حسابات انجام دیتا ہے۔ 3+ اجزاء کی فہرست کے لیے ہمیشہ dateComponents استعمال کریں۔
Calendar.compare مخصوص درستگی کے ساتھ دو Dates کا موازنہ کرتا ہے۔ toGranularity پیرامیٹر جزو کی درستگی کا تعین کرتا ہے: .year صرف سال کا موازنہ کرتا ہے، .month — سال اور مہینہ، .day — سال، مہینہ، دن۔ یہ جانچنے کے لیے مفید ہے کہ آیا دو تاریخیں وقت کو نظرانداز کرتے ہوئے ایک ہی دن پر آتی ہیں۔
let calendar = Calendar.current
let now = Date()
// ایک جزو نکالنا
let year = calendar.component(.year, from: now)
// اجزاء کا ایک سیٹ نکالنا
let comps = calendar.dateComponents(
[.year, .month, .day], from: now
)
// دن کی درستگی سے موازنہ
let isSameDay = calendar.compare(date1, to: date2,
toGranularity: .day) == .orderedSame
// چک کریں کہ تاریخ آج ہے
let isToday = calendar.isDateInToday(someDate)
Calendar.isDateInToday، isDateInTomorrow، isDateInYesterday — نسبتاً جانچ کے لیے طریقے۔ Calendar.isDate(_:inSameDayAs:) جانچتا ہے کہ آیا دو تاریخیں کیلنڈر کے ٹائم زون کو مدنظر رکھتے ہوئے ایک ہی کیلنڈر دن پر آتی ہیں۔ یہ طریقے اندرونی طور پر Calendar.compare استعمال کرتے ہیں اور بار بار کالز کے لیے بہتر بنائے گئے ہیں۔
Calendar.dateInterval تجزیہ اور یوزر انٹرفیس کے لیے سب سے مفید طریقوں میں سے ایک ہے۔ یہ مخصوص جزو کے لیے DateInterval لوٹاتا ہے: ایک دن، ہفتہ، مہینہ، سال کا آغاز اور اختتام۔ DateInterval میں start (Date) اور end (Date) — مدت کی حدود ہوتی ہیں۔ مثال کے طور پر، dateInterval(of: .weekOfYear, for: Date()) موجودہ ہفتے کے پیر کے آغاز اور اتوار کے اختتام کو لوٹاتا ہے۔
Calendar.date byAdding کے ساتھ — تاریخوں کو منتقل کرنے کا ایک طریقہ۔ Calendar.date(byAdding: .day, value: 7, to: Date()) ایک ہفتہ بعد کی تاریخ لوٹاتا ہے۔ Calendar.date(byAdding: DateComponents) ایک زیادہ لچکدار ورژن ہے جو ایک ساتھ متعدد اجزاء کو منتقل کرنے کی اجازت دیتا ہے: +1 مہینہ +3 دن۔ Calendar خود بخود مختلف مہینوں کی لمبائی اور لیپ ایئر کو مدنظر رکھتا ہے۔
Calendar.nextDate مخصوص DateComponents سے مماثل اگلی تاریخ تلاش کرتا ہے۔ matchingPolicy پیرامیٹر عدم مماثلت کی صورت میں رویے کی وضاحت کرتا ہے: .nextTime — وقت میں اگلی مماثلت، .nextTimePreservingSmallerComponents — اصل تاریخ سے منٹ اور سیکنڈ محفوظ رکھتا ہے، .strict — عین مماثلت کی ضرورت ہے۔
let calendar = Calendar.current
let today = Date()
// ہفتے کا آغاز اور اختتام
let weekInterval = calendar.dateInterval(
of: .weekOfYear, for: today
)!
// 1 مہینہ منتقل کریں
let nextMonth = calendar.date(
byAdding: .month, value: 1, to: today
)!
// DateComponents کے ذریعے منتقل کریں
var delta = DateComponents()
delta.month = 1
delta.day = 3
let shifted = calendar.date(byAdding: delta, to: today)!
// اگلا جمعہ 13
let friday13Components = DateComponents(
weekday: 6, day: 13
)
let nextFriday13 = calendar.nextDate(
after: today, matching: friday13Components,
matchingPolicy: .nextTime
)
EnumerateDates — پیٹرن کے مطابق تاریخوں پر اعادہ کرنے کا ایک طاقتور طریقہ۔ Calendar.enumerateDates(startingAfter:matching:matchingPolicy:using:) ہر مماثلت کے لیے ایک بلاک کو کال کرتا ہے جب تک کہ بلاک stop = true لوٹائے۔ کیلنڈرز اور نظام الاوقات میں بار بار ہونے والے واقعات پیدا کرنے کے لیے استعمال ہوتا ہے۔ یہ طریقہ nextDate کے ساتھ دستی لوپ سے زیادہ موثر ہے، کیونکہ یہ ICU کے ذریعے بہتر بنایا گیا ہے۔
TimeZone Calendar کا ایک لازمی حصہ ہے۔ ٹائم زون تعین کرتا ہے کہ مطلق Date کس کیلنڈر وقت سے مماثل ہے۔ UTC اور ماسکو میں ایک ہی Date مختلف اجزاء دیتا ہے: UTC میں Date() 10:00 دکھا سکتا ہے، جبکہ MSK میں — 13:00۔ Calendar.timeZone ڈیفالٹ طور پر TimeZone.current ہے۔
Locale ہفتے کے پہلے دن، سال کے پہلے ہفتے میں کم از کم دنوں کی تعداد (minDaysInFirstWeek) اور مہینے/ہفتے کے دنوں کے ناموں (DateFormatter کے ذریعے تبدیلی کے وقت) کو متاثر کرتا ہے۔ Calendar.locale ڈیفالٹ طور پر Locale.current ہے۔ روسی علاقائی ترتیبات میں ہفتہ پیر سے شروع ہوتا ہے، امریکی ترتیبات میں — اتوار سے۔
Calendar.availableIdentifiers تمام معاون کیلنڈر شناخت کنندگان کی فہرست لوٹاتا ہے۔ جامد خاصیت Calendar.availableCalendarIdentifiers ایک ہی شناخت کنندگان کے ساتھ سٹرنگز کی ایک صف ہے۔ کیلنڈر انتخاب کا انٹرفیس بنانے اور ڈیوائس پر کسی مخصوص کیلنڈر سسٹم کی دستیابی جانچنے کے لیے استعمال ہوتا ہے۔
// مخصوص ٹائم زون کے ساتھ Calendar
var utcCalendar = Calendar(identifier: .gregorian)
utcCalendar.timeZone = TimeZone(identifier: "UTC")!
// روسی علاقہ ترتیبات کے ساتھ Calendar
var russianCalendar = Calendar(identifier: .gregorian)
russianCalendar.locale = Locale(identifier: "ru_RU")
// پہلا کاری دن علاقہ ترتیبات پر منحصر ہے
let firstWeekday = russianCalendar.firstWeekday
// 2 = پیر (ru_RU میں)
// دستیاب کیلنڈروں کی فہرست
for identifier in Calendar.availableIdentifiers {
print(identifier)
}
firstWeekday — Calendar کی ایک خاصیت جو تعین کرتی ہے کہ ہفتے کا کون سا دن پہلا مانا جاتا ہے۔ روسی علاقائی ترتیبات میں Sunday = 2 (پیر پہلا ہے)۔ امریکی علاقائی ترتیبات میں Sunday = 1۔ یہ weekOfMonth اور weekOfYear کو متاثر کرتا ہے: ایک ہی تاریخ مختلف علاقائی ترتیبات میں مختلف ہفتہ نمبروں سے تعلق رکھ سکتی ہے۔ تاریخوں کے ساتھ کام کرنے والی ایپلیکیشنز کے لیے Calendar.current استعمال کریں یا واضح طور پر firstWeekday مقرر کریں۔
آئیے عملی منظرناموں پر غور کریں جو Calendar کی صلاحیتوں کو ظاہر کرتے ہیں۔ ہر مثال ایک مخصوص iOS ڈیولپمنٹ کام کو حل کرتی ہے اور کیلنڈر حسابات کے استعمال کا صحیح طریقہ دکھاتی ہے۔
Calendar.dateInterval(of: .month, for:) موجودہ مہینے کی حدود لوٹاتا ہے۔ یہ جانچنا کہ آیا ایک Date اس وقفے کے اندر آتا ہے یہ تعین کرنے کا تیز ترین طریقہ ہے کہ آیا کوئی تاریخ موجودہ مہینے سے تعلق رکھتی ہے۔ ایک متبادل طریقہ .month درستگی کے ساتھ Calendar.compare ہے: اگر نتیجہ .orderedSame ہے تو مہینہ مماثل ہے۔
func isInCurrentMonth(_ date: Date) -> Bool {
let calendar = Calendar.current
let monthInterval = calendar.dateInterval(
of: .month, for: Date()
)!
return monthInterval.contains(date)
}
// ایک مہینے میں دنوں کی تعداد
func daysInMonth(for date: Date) -> Int {
let calendar = Calendar.current
return calendar.range(
of: .day, in: .month, for: date
)?.count ?? 0
}
// صحیح سماپتی کے ساتھ مہینے شامل کرنا
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:) کسی دوسرے جزو کے سیاق و سباق میں مخصوص جزو کے لیے قابل قبول اقدار کی حد لوٹاتا ہے۔ مثال کے طور پر، range(of: .day, in: .month, for: date) 31 دن والے مہینوں کے لیے 1..<32 یا غیر لیپ سال میں فروری کے لیے 1..<29 لوٹاتا ہے۔ ہارڈ کوڈڈ ویلیوز استعمال کرنے کے بجائے مہینے میں دنوں کی تعداد جاننے کا یہ صحیح طریقہ ہے۔
مہینے شامل کرنا Calendar.date(byAdding:value:to:) کے ذریعے حدی تاریخیں درست طریقے سے ہینڈل کرتا ہے۔ اگر 31 جنوری میں 1 مہینہ شامل کیا جائے تو Calendar 28 فروری (یا لیپ سال میں 29) لوٹاتا ہے، نہ کہ 3 مارچ جو TimeInterval کے ذریعے صرف 30 دن شامل کرنے پر حاصل ہوگا۔ کیلنڈر حسابات کے لیے TimeInterval استعمال نہ کرنے کی یہ ایک اور وجہ ہے۔
| Calendar طریقہ | مقصد | مثال |
|---|---|---|
| dateInterval | مدت کی حدود | مہینے کا آغاز اور اختتام |
| range(of:in:for:) | جزو کی حد | موجودہ مہینے میں دن |
| date(byAdding:) | تاریخ کی منتقلی | آج سے +1 مہینہ |
| isDateInToday | آج کی جانچ | کیا تاریخ آج کی ہے؟ |
| compare(toGranularity:) | درستگی کے ساتھ موازنہ | وقت کو نظرانداز کرتے ہوئے ایک ہی دن |
اکثر پوچھے گئے سوالات
Calendar.current صارف کی سسٹم ترتیبات سے کیلنڈر لوٹاتا ہے — یہ گریگورین نہیں ہو سکتا (مثال کے طور پر تھائی لینڈ میں بدھ)۔ Calendar(identifier: .gregorian) ترتیبات سے قطع نظر ہمیشہ ایک گریگورین کیلنڈر بناتا ہے۔ تاریخوں کی نمائش کے لیے Calendar.current استعمال کریں اور کاروباری منطق کے لیے واضح طور پر منتخب کردہ شناخت کنندہ استعمال کریں۔
یہ مہینوں کی مختلف لمبائی کی وجہ سے ہے۔ اگر موجودہ تاریخ 31 جنوری ہے تو 1 مہینہ شامل کرنے سے 28 فروری ملتا ہے، کیونکہ فروری میں 31 دن نہیں ہوتے۔ Calendar خود بخود تاریخ کو مہینے کے آخری درست دن تک ایڈجسٹ کرتا ہے۔ درست کنٹرول کے لیے، مہینے کے پہلے دن جانے کے لیے day: 1 کے ساتھ DateComponents استعمال کریں۔
DateFormatter Calendar.current — صارف کا سسٹم کیلنڈر استعمال کرتا ہے۔ اگر کسی ایپلیکیشن کو ترتیبات سے قطع نظر ہمیشہ گریگورین کیلنڈر میں تاریخیں دکھانی چاہئیں تو formatter.calendar = Calendar(identifier: .gregorian) مقرر کریں۔ یہ تمام صارفین کے لیے یکساں نمائش کو یقینی بناتا ہے۔
Calendar.range(of: .day, in: .year, for: date) 365 یا 366 دن لوٹاتا ہے۔ آسان: Calendar.date(from: DateComponents(year: year, month: 2, day: 29)) != nil — اگر 29 فروری موجود ہے تو سال لیپ سال ہے۔ Calendar مخصوص کیلنڈر سسٹم کے قواعد خود بخود ہینڈل کرتا ہے۔
ہاں، firstWeekday خاصیت قابل تحریر ہے۔ تبدیلی weekOfMonth، weekOfYear اور ہفتہ نمبروں سے متعلق تمام حسابات کو متاثر کرتی ہے۔ locale = Locale(identifier: “ru_RU”) مقرر کرنے پر firstWeekday خود بخود 2 (پیر) ہو جاتا ہے۔ دستی ترتیب locale سے قیمت کو اوور رائیڈ کرتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں