Joda-Time Java में दिनांक और समय के साथ काम करने के लिए एक लाइब्रेरी है, जिसे Stephen Colebourne ने बोझिल java.util.Date और java.util.Calendar के विकल्प के रूप में बनाया था। Java 8 के रिलीज़ से पहले, यह लाइब्रेरी औद्योगिक विकास में दिनांक प्रबंधन के लिए वास्तविक मानक थी, जिसमें Android एप्लिकेशन भी शामिल थे। Oracle Java Magazine (2023) के अनुसार, Android API 26 के रिलीज़ होने के दो वर्षों के भीतर 60% से अधिक प्रोजेक्ट Joda-Time से java.time में माइग्रेट हो गए।
मुख्य बिंदु
Joda-Time एक ओपन-सोर्स लाइब्रेरी (Apache 2.0) है जो Java भाषा में java.util.Date और java.util.Calendar कक्षाओं के लिए गुणवत्तापूर्ण प्रतिस्थापन प्रदान करती है। इस परियोजना की स्थापना Stephen Colebourne ने 2004 में मानक दिनांक और समय API की अनेक समस्याओं के जवाब में की थी, जिसमें परिवर्तनशीलता, स्वरूपण जटिलता और सीमित समय क्षेत्र समर्थन शामिल थे। लाइब्रेरी को Java समुदाय में व्यापक रूप से अपनाया गया और हजारों परियोजनाओं द्वारा उपयोग किया गया, जिसमें बड़े एंटरप्राइज़ सिस्टम और Android एप्लिकेशन शामिल थे, जहाँ अंतर्निहित दिनांक प्रबंधन उपकरण विशेष रूप से असुविधाजनक थे। 2014 में Java 8 के रिलीज़ और java.time पैकेज (JSR-310) की शुरुआत के बाद से, लाइब्रेरी को रखरखाव मोड में डाल दिया गया है — नई सुविधाएँ नहीं जोड़ी जा रही हैं, और मौजूदा कार्यक्षमता नए API द्वारा पूरी तरह से कवर की गई है।
Joda-Time अपरिवर्तनीयता के सिद्धांत पर बनाई गई है: निर्माण के बाद प्रत्येक दिनांक या समय ऑब्जेक्ट को बदला नहीं जा सकता। कोई भी ऑपरेशन — एक दिन जोड़ना, महीना बदलना, समय क्षेत्र सेट करना — एक नया ऑब्जेक्ट लौटाता है, मूल को अपरिवर्तित छोड़ देता है। यह दृष्टिकोण ऑब्जेक्ट्स के अनजाने संशोधन से जुड़ी त्रुटियों के वर्ग को पूरी तरह से समाप्त कर देता है जो परिवर्तनशील java.util.Date और java.util.Calendar की विशेषता थी। अपरिवर्तनीय डिज़ाइन लाइब्रेरी को अतिरिक्त सिंक्रनाइज़ेशन के बिना थ्रेड-सेफ भी बनाता है।
लाइब्रेरी विभिन्न परिदृश्यों के लिए कई मुख्य कक्षाएं प्रदान करती है: DateTime — समय क्षेत्र के साथ पूर्ण दिनांक और समय, LocalDate — समय के बिना केवल दिनांक, LocalTime — दिनांक के बिना केवल समय, LocalDateTime — समय क्षेत्र बंधन के बिना दिनांक और समय। इसके अतिरिक्त, अंतराल (Interval), अवधि (Period) और अवधि (Duration) के साथ काम करने के लिए कक्षाएं शामिल की गई हैं, जो आपको माप की विभिन्न इकाइयों में समय में दो बिंदुओं के बीच अंतर की गणना करने की अनुमति देती हैं। प्रत्येक कक्षा एक समान हैंडलिंग के लिए ReadableInstant या ReadablePartial इंटरफ़ेस को लागू करती है।
Java में मानक दिनांक API की समस्या प्लेटफ़ॉर्म की शुरुआत से ही ज्ञात थी। java.util.Date और java.util.Calendar कक्षाओं में मूलभूत कमियाँ थीं: महीनों की संख्या 0 से शुरू होती थी, Date एक साथ दिनांक और समय दोनों का प्रतिनिधित्व करता था, Calendar परिवर्तनशील था और जटिल कॉन्फ़िगरेशन की आवश्यकता थी। SimpleDateFormat के माध्यम से स्वरूपण थ्रेड-सेफ नहीं था — मल्टीथ्रेडेड एप्लिकेशन में यह गलत दिनांक पार्सिंग की ओर ले जाता था। Stephen Colebourne, दिनांकों के गहन उपयोग वाली परियोजनाओं पर काम करते हुए, एक विकल्प बनाने का निर्णय लिया जो इन सभी समस्याओं को ठीक करे।
InfoQ (2014) पर एक साक्षात्कार के अनुसार, Colebourne ने पहले सार्वजनिक रिलीज़ से पहले एक वर्ष से अधिक समय तक उत्पादन परियोजनाओं में Joda-Time का परीक्षण किया। पहला संस्करण 2004 में जारी किया गया और तुरंत समुदाय का ध्यान आकर्षित किया। 2010 तक, लाइब्रेरी अधिकांश Java परियोजनाओं में एक मानक निर्भरता बन गई थी, जिसमें Spring और Hibernate जैसे फ्रेमवर्क शामिल थे। Joda-Time की सफलता ने सीधे JSR-310 विनिर्देश (Date and Time API) को प्रभावित किया, जिसे Java 8 में शामिल किया गया — उसी Stephen Colebourne के साथ विनिर्देश प्रमुख के रूप में।
Joda-Time ने केवल दिनांक समस्या को हल नहीं किया — इसने Java में API डिज़ाइन के दृष्टिकोण को बदल दिया। अपरिवर्तनीय मान ऑब्जेक्ट्स की अवधारणा, जिसे लाइब्रेरी द्वारा प्रदर्शित किया गया, को Java 8 में सभी नए API के लिए एक मानक के रूप में अपनाया गया। इसके अलावा, Joda-Time की लोकप्रियता ने Oracle को दिखाया कि समुदाय निम्न-गुणवत्ता वाली मानक लाइब्रेरीज़ को सहन करने को तैयार नहीं है — Joda-Time के बाद, Java में फ़ाइल हैंडलिंग (NIO.2), समय (java.time) और वैकल्पिक मानों (Optional) के लिए API को पुनः डिज़ाइन किया गया।
Joda-Time सुविधाओं का एक सेट प्रदान करती है जो Java 8 से पहले मानक लाइब्रेरी में उपलब्ध नहीं था। मुख्य लाभों में स्वचालित डेलाइट सेविंग टाइम हैंडलिंग के साथ 200+ समय क्षेत्रों के लिए समर्थन, पैटर्न और लोकेल के साथ एक समृद्ध स्वरूपण API, साथ ही विभिन्न इकाइयों — वर्ष, महीने, दिन, घंटे — में दिनांकों के बीच अवधि गणना शामिल है। विशेष उल्लेख के योग्य है अंतराल प्रणाली: Interval (दो क्षणों के बीच एक अवधि), Period (कैलेंडर इकाइयों में अंतर) और Duration (मिलीसेकंड में सटीक लंबाई)।
Joda-Time में DateTimeFormatter क्लास थ्रेड-सेफ दिनांक स्वरूपण प्रदान करता है — java.text.SimpleDateFormat के विपरीत। फ़ॉर्मेटर पैटर्न (जैसे, “yyyy-MM-dd HH:mm:ss”) या स्थानीयकृत आउटपुट के लिए शैलियों (SHORT, MEDIUM, LONG, FULL) के माध्यम से बनाए जा सकते हैं। लाइब्रेरी फ़ॉर्मेटर कैशिंग का भी समर्थन करती है, जो उच्च-लोड अनुप्रयोगों में प्रदर्शन को गति देती है। स्ट्रिंग्स से दिनांकों का पार्सिंग सख्ती नियंत्रण के साथ किया जाता है — आप अधूरी या गलत दिनांकों की अनुमति या अस्वीकार कर सकते हैं।
Joda-Time के मजबूत बिंदुओं में से एक समय अंतराल के साथ काम करना है। Interval क्लास दो क्षणों के बीच एक सटीक समय अवधि का प्रतिनिधित्व करता है और प्रतिच्छेदन, संघ और समाहित जाँच संचालन का समर्थन करता है। Period, Interval के विपरीत, कैलेंडर इकाइयों में संचालित होता है — उदाहरण के लिए, 1 मार्च और 1 अप्रैल के बीच का अंतर ठीक 1 महीना है, हालाँकि अवधि में यह 28–31 दिन हो सकता है। Duration, दूसरी ओर, कैलेंडर बंधन के बिना मिलीसेकंड में सटीक लंबाई का प्रतिनिधित्व करता है और संचालन निष्पादन समय को मापने के लिए उपयुक्त है।
import org.joda.time.*;
import org.joda.time.format.*;
DateTime now = new DateTime();
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
String formatted = fmt.print(now);
DateTime nextWeek = now.plusWeeks(1);
Period period = new Period(now, nextWeek);
int days = period.getDays(); // दिन = 7
Interval interval = new Interval(now, nextWeek);
boolean contains = interval.contains(now); // सत्य
java.time पैकेज (JSR-310) उसी लेखक — Stephen Colebourne — द्वारा विकसित किया गया था और दस वर्षों के परिचालन अनुभव के साथ Joda-Time के सर्वोत्तम विचारों को शामिल किया। दोनों API अपरिवर्तनीय कक्षाओं का उपयोग करते हैं, समय क्षेत्रों का समर्थन करते हैं और संचालन का एक समृद्ध सेट प्रदान करते हैं। हालाँकि, java.time Java मानक लाइब्रेरी में पूरी तरह से एकीकृत है, किसी बाहरी निर्भरता की आवश्यकता नहीं है और अधिक सुसंगत नामकरण प्रणाली का उपयोग करता है: ReadableInstant के बजाय Instant, LocalDate के बजाय LocalDate (नाम संरक्षित), DateTime के बजाय ZonedDateTime।
| विशेषता | Joda-Time | java.time |
|---|---|---|
| रिलीज़ वर्ष | 2004 | 2014 (Java 8) |
| स्थिति | रखरखाव | सक्रिय विकास |
| आधार दिनांक/समय | DateTime | ZonedDateTime |
| केवल दिनांक | LocalDate | LocalDate |
| अपरिवर्तनीयता | हाँ | हाँ |
| स्वरूपण | DateTimeFormatter | DateTimeFormatter |
| दिनांक अंतर | Period / Duration | Period / Duration |
java.time Joda-Time के कई आर्किटेक्चरल निर्णयों को ठीक करता है। पहला, java.time null लौटाने वाली विधियों और लापता मानों के बीच भ्रम को समाप्त करता है — इसके बजाय Optional का उपयोग करता है। दूसरा, Chronology इंटरफ़ेस के माध्यम से वैकल्पिक कैलेंडर सिस्टम (जापानी, थाई, इस्लामिक) के लिए समर्थन जोड़ा गया है। तीसरा, java.time में कैलेंडर बंधन के बिना UTC समय क्षणों के साथ काम करने के लिए Instant क्लास शामिल है — यह नेटवर्क प्रोटोकॉल और डेटाबेस के साथ एकीकरण को सरल बनाता है। Android के लिए, API 26 (Android 8.0) से शुरू करके java.time का उपयोग करने की अनुशंसा की जाती है या पुराने संस्करणों के लिए desugaring के माध्यम से।
Joda-Time से java.time में माइग्रेशन एक ऐसी प्रक्रिया है जिसे लाइब्रेरी लेखकों ने यथासंभव सुरक्षित और पूर्वानुमानित बनाने का प्रयास किया। अधिकांश कक्षाओं के सीधे समकक्ष हैं: DateTime → ZonedDateTime, LocalDate → LocalDate (नाम मेल खाता है), LocalTime → LocalTime, DateTimeZone → ZoneId, Period → Period, Duration → Duration। मुख्य परिवर्तन ऑब्जेक्ट बनाने के तरीके और विधि नामों से संबंधित हैं — उदाहरण के लिए, `now.toDate()` के बजाय, `Date.from(instant)` का उपयोग करें, और `DateTime.now()` को `ZonedDateTime.now()` से बदल दिया गया है।
माइग्रेशन को एक पतली अमूर्त परत में Joda-Time को अलग करके शुरू करने की अनुशंसा की जाती है — यह पूरे कोडबेस को छुए बिना लाइब्रेरी को चरणबद्ध रूप से बदलने की अनुमति देता है। पहला कदम आमतौर पर LocalDate और LocalTime के साथ काम को बदलना है — इन कक्षाओं में लाइब्रेरीज़ के बीच सबसे कम अंतर हैं। दूसरे चरण में DateTime (ZonedDateTime में) और समय क्षेत्रों को माइग्रेट किया जाता है। तीसरे चरण में Interval, Period और Duration को बदला जाता है — यहाँ आपको डेलाइट सेविंग टाइम व्यवहार की सावधानीपूर्वक जाँच करने की आवश्यकता है। माइग्रेशन पूरा होने के बाद, Joda-Time को प्रोजेक्ट निर्भरताओं से पूरी तरह से हटा दिया जाता है।
// Joda-Time (माइग्रेशन से पहले)
val dateTime = DateTime.now(DateTimeZone.forID("Europe/Moscow"))
val formatted = dateTime.toString("dd.MM.yyyy")
val plusDay = dateTime.plusDays(1)
// java.time (माइग्रेशन के बाद)
val zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))
val formatted2 = zonedDateTime.format(
DateTimeFormatter.ofPattern("dd.MM.yyyy")
)
val plusDay2 = zonedDateTime.plusDays(1)
Joda-Time से java.time में संक्रमण को सरल बनाने के लिए कई उपयोगिताएँ मौजूद हैं। OpenRewrite (Moderne द्वारा) org.openrewrite.java.migrate.JodaTimeToJavaTime रेसिपी के माध्यम से स्वचालित माइग्रेशन का समर्थन करता है — यह प्रोग्राम लॉजिक को संरक्षित करते हुए कक्षाओं, विधियों और आयातों को बदलता है। Gradle प्रोजेक्ट्स के लिए, de.fayard.refreshVersions प्लगइन में भी माइग्रेशन नियम शामिल हैं। मैन्युअल रूप से, IDEA के साथ माइग्रेशन करना सबसे आसान है: Java Time Migration Assistant प्लगइन Joda-Time कॉल को हाइलाइट करता है और java.time में संबंधित प्रतिस्थापन सुझाता है, जो मैन्युअल प्रतिस्थापन की तुलना में प्रक्रिया को 2–3 गुना तेज करता है।
आइए Android एप्लिकेशन में Joda-Time के साथ काम करने के व्यावहारिक उदाहरण देखें। लाइब्रेरी स्थानीय मानकों के अनुसार दिनांकों को स्वरूपित करने, उपयोगकर्ता की आयु की गणना करने, घटनाओं की अवधि निर्धारित करने और दो दिनांकों के बीच अंतराल की गणना करने के लिए विशेष रूप से उपयोगी है। सभी उदाहरण अपरिवर्तनीय ऑब्जेक्ट्स का उपयोग करते हैं — प्रत्येक कॉल एक नया उदाहरण लौटाता है, जबकि मूल ऑब्जेक्ट अपरिवर्तित रहता है।
// उपयोगकर्ता की आयु की गणना करें
val birthDate = LocalDate.parse("1990-05-15")
val today = LocalDate.now()
val age = Years.yearsBetween(birthDate, today).getYears()
// आयु == 36
// उपयोगकर्ता लोकेल के साथ प्रारूपित करें
val dateTime = DateTime.now()
val formatter = DateTimeFormat.forStyle("MM").withLocale(Locale.getDefault())
val localized = formatter.print(dateTime)
Joda-Time में अंतराल आपको समय अंतराल ओवरलैप की जाँच, प्रतिच्छेदन की गणना और निकटतम घटना खोजने जैसे कार्यों को कुशलतापूर्वक हल करने की अनुमति देते हैं। उदाहरण के लिए, कैलेंडर एप्लिकेशन विकसित करते समय, आप जाँच सकते हैं कि कोई नई घटना मौजूदा घटनाओं के साथ ओवरलैप होती है या नहीं। Interval क्लास contains, overlaps, gap और abuts संचालन का समर्थन करता है — अंतिम यह दिखाता है कि क्या अंतराल अपनी सीमाओं पर स्पर्श करते हैं। Duration का उपयोग मिलीसेकंड सटीकता के साथ दो क्षणों के बीच की लंबाई मापने के लिए किया जाता है।
// अंतराल ओवरलैप जांचें
Interval meeting1 = new Interval(
new DateTime(2026, 7, 21, 10, 0),
new DateTime(2026, 7, 21, 11, 0)
);
Interval meeting2 = new Interval(
new DateTime(2026, 7, 21, 10, 30),
new DateTime(2026, 7, 21, 11, 30)
);
boolean overlaps = meeting1.overlaps(meeting2); // सत्य
Duration gap = meeting1.gap(meeting2); // शून्य (कोई अंतर नहीं)
अक्सर पूछे जाने वाले प्रश्न
Joda-Time Java में दिनांक और समय के साथ काम करने के लिए एक लाइब्रेरी है, जो Java 8 के रिलीज़ से पहले बनाई गई थी। इसने java.util.Date और java.util.Calendar की कमियों को ठीक किया: परिवर्तनशीलता, 0 से महीने की संख्या, पूर्ण समय क्षेत्र समर्थन की कमी और गैर-थ्रेड-सेफ स्वरूपण।
Java.time (JSR-310) Joda-Time का उत्तराधिकारी है, जो उसी लेखक द्वारा विकसित किया गया है। मुख्य अंतर: java.time Java 8+ मानक लाइब्रेरी में निर्मित है, अधिक सुसंगत नामकरण प्रणाली का उपयोग करता है, वैकल्पिक कैलेंडर सिस्टम का समर्थन करता है और UTC समय के साथ काम करने के लिए Instant क्लास शामिल करता है।
नहीं, नए प्रोजेक्ट्स के लिए java.time का उपयोग करने की अनुशंसा की जाती है। Joda-Time 2014 से रखरखाव मोड में है और अब नई सुविधाएँ प्राप्त नहीं करता है। Android API 26+ के लिए, java.time मूल रूप से उपलब्ध है, और पुराने संस्करणों के लिए desugaring का उपयोग किया जाता है — एक तंत्र जो API 19+ वाले उपकरणों पर java.time का उपयोग करने की अनुमति देता है।
माइग्रेशन चरण दर चरण किया जाता है: Joda-Time को अमूर्तताओं में अलग करें, पहले LocalDate और LocalTime बदलें, फिर DateTime → ZonedDateTime, और अंत में Period, Duration और Interval। OpenRewrite उपकरण JodaTimeToJavaTime रेसिपी के माध्यम से स्वचालित माइग्रेशन का समर्थन करता है, जो प्रक्रिया को 2–3 गुना तेज करता है।
DateTime → ZonedDateTime, LocalDate → LocalDate (मेल खाता है), LocalTime → LocalTime, LocalDateTime → LocalDateTime, DateTimeZone → ZoneId, Interval → कोई सीधा समकक्ष नहीं (Instant + Duration का संयोजन उपयोग किया जाता है), Period → Period, Duration → Duration। विधि नाम भी समान हैं: plusDays, minusMonths, withZone दोनों लाइब्रेरीज़ में उपलब्ध हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें