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 निर्दिष्ट सटीकता के साथ दो Date की तुलना करता है। 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 विश्लेषण और UI के लिए सबसे उपयोगी विधियों में से एक है। यह निर्दिष्ट घटक के लिए 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 समान पहचानकर्ताओं वाली स्ट्रिंग्स की एक सरणी है। कैलेंडर चयन UI बनाने और डिवाइस पर किसी विशिष्ट कैलेंडर प्रणाली की उपलब्धता की जाँच करने के लिए उपयोग किया जाता है।
// विशिष्ट समय क्षेत्र के साथ 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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें