CodeGym /Java Blog /अनियमित /समय में कैसे न खोएं: दिनांक समय और कैलेंडर
John Squirrels
स्तर 41
San Francisco

समय में कैसे न खोएं: दिनांक समय और कैलेंडर

अनियमित ग्रुप में प्रकाशित
नमस्ते! आज हम एक नए डेटा प्रकार के साथ काम करना शुरू करेंगे जिसका सामना हमने पहले नहीं किया है, अर्थात् दिनांक। समय में खोया कैसे नहीं: दिनांक समय और कैलेंडर - 1मुझे नहीं लगता कि मुझे यह बताने की जरूरत है कि तारीख क्या है। :) सिद्धांत रूप में, हम वर्तमान दिनांक और समय को एक साधारण जावा स्ट्रिंग में संग्रहीत कर सकते हैं।

public class Main {
   public static void main(String[] args) {

       String date = "June 11, 2018";
       System.out.println(date);
   }
}
लेकिन इस तरीके में कई कमियां हैं। कक्षा Stringको पाठ के साथ काम करने के लिए डिज़ाइन किया गया है, और इसके तरीके इस कार्य के लिए उपयुक्त हैं। अगर हमें किसी तारीख में हेरफेर करने की ज़रूरत है (उदाहरण के लिए 2 घंटे जोड़ें), तो यह Stringइतना अच्छा काम नहीं करता है। या यदि हम प्रोग्राम के कंपाइल होने की वर्तमान तिथि और समय को प्रदर्शित करना चाहते हैं। Stringयहाँ भी मदद नहीं करता है: जब तक आप कोड लिखते हैं और इसे चलाते हैं, तब तक समय बदल चुका होगा और कंसोल गलत जानकारी प्रदर्शित करेगा। इसलिए जावा के रचनाकारों ने दिनांक और समय के साथ काम करने के लिए कई कक्षाएं प्रदान कीं। इनमें से पहला हैjava.util.Date

तिथि वर्ग

हमने इसका पूरा नाम निर्दिष्ट किया है, क्योंकि दूसरे जावा पैकेज में java.sql.Dateक्लास है। उन्हें मत मिलाओ! इसके बारे में आपको सबसे पहले जानने की जरूरत है कि यह दिनांक को मिलीसेकंड की संख्या के रूप में संग्रहीत करता है जो 1 जनवरी, 1970 से पारित हो गया है। इस समय प्रणाली का अपना नाम भी है: " यूनिक्स-टाइम " एक दिलचस्प दृष्टिकोण, होगा' क्या आप सहमत हैं? :) याद रखने योग्य दूसरी बात यह है: यदि आप Dateडिफॉल्ट कन्स्ट्रक्टर का उपयोग करके ऑब्जेक्ट बनाते हैं, तो परिणाम वस्तु के निर्माण के समय वर्तमान दिनांक और समय का प्रतिनिधित्व करता है । याद रखें कि हमने कहा था कि इस तरह के कार्य के साथ एक तारीख के रूप में प्रतिनिधित्व किया जाएगा String? वर्ग Dateइसे आसानी से संभाल लेता है।

public class Main {
   public static void main(String[] args) {

       Date date = new Date();
       System.out.println(date);
   }
}
इस कोड को कई बार चलाएँ, और आप बार-बार समय परिवर्तन देखेंगे। :) यह संभव है क्योंकि समय को मिलीसेकंड के रूप में संग्रहीत किया जाता है: वे समय की बहुत छोटी इकाइयाँ हैं, इसलिए परिणाम अत्यधिक सटीक होते हैं। वर्ग Dateअन्य निर्माता: आप 1 जनवरी, 1970 को 00:00 बजे से आवश्यक तिथि तक मिलीसेकंड की सटीक संख्या पास कर सकते हैं, और एक संबंधित दिनांक ऑब्जेक्ट बनाया जाएगा:

public class Main {
   public static void main(String[] args) {

       Date date = new Date(1212121212121L);
       System.out.println(date);
   }
}
कंसोल आउटपुट: शुक्र 30 मई 04:20:12 जीएमटी 2008 हमें 30 मई 2008 मिलता है। "शुक्र" सप्ताह के दिन (शुक्रवार, डुह) को इंगित करता है, और जीएमटी समय क्षेत्र (ग्रीनविच मीन टाइम) है। मिलीसेकंड को एस के रूप में पारित किया जाता है long, क्योंकि मिलीसेकंड की संख्या आमतौर पर एक में फिट नहीं होती है int। तो, तारीखों के साथ कौन से ऑपरेशन हमें करने पड़ सकते हैं? खैर, सबसे स्पष्ट, ज़ाहिर है, तुलना है । यह निर्धारित करने के लिए कि एक तारीख दूसरी से पहले आती है या बाद में। यह कई मायनों में किया जा सकता है। उदाहरण के लिए, आप उस Date.getTime()विधि को कॉल कर सकते हैं, जो 1 जनवरी, 1970 की आधी रात के बाद से मिलीसेकंड की संख्या लौटाती है। बस इसे दो दिनांक वस्तुओं पर कॉल करें और परिणामों की तुलना करें:

public class Main {
   public static void main(String[] args) {

       Date date1 = new Date();

       Date date2 = new Date();

       System.out.println((date1.getTime() > date2.getTime())?
               "date1 is later than date2" : "date1 is earlier than date2");
   }
}
आउटपुट: दिनांक 1 दिनांक 2 से पहले है लेकिन एक अधिक सुविधाजनक तरीका भी है, अर्थात दिनांक वर्ग द्वारा प्रदान की गई विशेष विधियों का उपयोग करके before(): after()और equals()। वे सभी एक बूलियन मान लौटाते हैं। यह before()विधि जाँचती है कि क्या हमारी तिथि तर्क के रूप में पारित तिथि से पहले है:

public class Main {
   public static void main(String[] args) throws InterruptedException {

       Date date1 = new Date();

       Thread.sleep(2000);// Suspend the program for 2 seconds
       Date date2 = new Date();

       System.out.println(date1.before(date2));
   }
}
कंसोल आउटपुट: सच इसी तरह, यह after()देखने के लिए विधि जांचती है कि क्या हमारी तिथि तर्क के रूप में पारित तिथि से बाद में है:

public class Main {
   public static void main(String[] args) throws InterruptedException {

       Date date1 = new Date();

       Thread.sleep(2000);// Suspend the program for 2 seconds
       Date date2 = new Date();

       System.out.println(date1.after(date2));
   }
}
कंसोल आउटपुट: गलत हमारे उदाहरणों में, हम 2 सेकंड के लिए "प्रोग्राम को सोने के लिए रख देते हैं", ताकि दो तिथियों के अलग-अलग होने की गारंटी हो। date1तेज़ कंप्यूटरों पर, और के निर्माण के बीच का समय date2एक मिलीसेकंड से कम हो सकता है, जिससे दोनों before()और after()झूठी वापसी होती है। लेकिन इस मामले में, equals()विधि सच हो जाएगी! आखिरकार, यह प्रत्येक तिथि के लिए 1 जनवरी, 1970 को 00:00 बजे से मिलीसेकंड की संख्या की तुलना करता है । वस्तुओं को तभी बराबर माना जाता है जब वे मिलीसेकंड से मेल खाते हों :

public static void main(String[] args) {

   Date date1 = new Date();
   Date date2 = new Date();

   System.out.println(date1.getTime());
   System.out.println(date2.getTime());

   System.out.println(date1.equals(date2));
}
यहां आपको एक और बात ध्यान देने की जरूरत है। यदि आप OracleDate वेबसाइट पर कक्षा के लिए दस्तावेज़ खोलते हैं , तो आप देखेंगे कि इसके कई तरीके और निर्माता पदावनत के रूप में चिह्नित किए गए हैं (अर्थात उपयोग के लिए अनुशंसित नहीं)। यहां बताया गया है कि जावा के रचनाकारों को कक्षाओं के उन हिस्सों के बारे में क्या कहना है जिन्हें बहिष्कृत कर दिया गया है:
"एक प्रोग्राम एलिमेंट एनोटेट किया गया @Deprecated कुछ प्रोग्रामर को उपयोग करने की अनुशंसा नहीं की जाती है, आमतौर पर क्योंकि यह खतरनाक है, या क्योंकि एक बेहतर विकल्प है।"
इसका मतलब यह नहीं है कि इन विधियों का उपयोग बिल्कुल नहीं किया जा सकता है। यदि आप किसी IDE में बहिष्कृत विधियों का उपयोग करके कोड चलाने का प्रयास करते हैं, तो यह सबसे अधिक काम करेगा। उदाहरण के लिए, पदावनत विधि पर विचार करें , जो किसी वस्तु Date.getHours()से जुड़े घंटों की संख्या लौटाती है।Date

public static void main(String[] args) {

   Date date1 = new Date();

   System.out.println(date1.getHours());
}
यदि आप 14:21 (2:21 अपराह्न) पर कोड शुरू करते हैं, तो यह संख्या 14 प्रदर्शित करेगा। जैसा कि आप देख सकते हैं, बहिष्कृत विधि को पार कर लिया गया है, लेकिन यह अभी भी काम करता है। मौजूदा कोड के विशाल निकाय को तोड़ने के लिए इन विधियों को हटाया नहीं जाता है जो उनका उपयोग करता है। दूसरे शब्दों में, ये विधियाँ न तो "टूटी" हैं और न ही "हटाई गई" हैं। उन्हें उपयोग के लिए अनुशंसित नहीं किया जाता है क्योंकि एक अधिक सुविधाजनक विकल्प उपलब्ध है। संयोग से, प्रलेखन विशेष रूप से इस विकल्प का उल्लेख करता है:
समय में खोया कैसे नहीं: दिनांक समय और कैलेंडर - 2
कक्षा के अधिकांश Dateतरीकों को बेहतर और विस्तारित Calendarवर्ग में स्थानांतरित कर दिया गया है। आगे हम उस वर्ग से परिचित होंगे। :)

कैलेंडर वर्ग

JDK 1.1 ने एक नया वर्ग पेश किया: Calendar. इसने जावा में तारीखों के साथ काम करना पहले से कुछ आसान बना दिया। Calendarजिस वर्ग के साथ हम काम करेंगे उसका एकमात्र कार्यान्वयन वर्ग है GregorianCalendar। यह ग्रेगोरियन कैलेंडर को लागू करता है, जिसे दुनिया के अधिकांश देशों द्वारा देखा जाता है। इसका मुख्य लाभ यह है कि यह तिथियों के साथ अधिक सुविधाजनक प्रारूप में काम कर सकता है। उदाहरण के लिए, यह कर सकता है:
  • वर्तमान तिथि में एक महीना या दिन जोड़ें
  • जांचें कि क्या वर्ष एक लीप वर्ष है;
  • तिथि के अलग-अलग घटकों को लौटाएं (उदाहरण के लिए, पूरी तारीख से महीने की संख्या निकालें)
  • इसमें स्थिरांकों की एक बहुत सुविधाजनक प्रणाली भी शामिल है (जिनमें से कई हम नीचे देखेंगे)।
वर्ग की एक अन्य महत्वपूर्ण वृद्धि इसका कैलेंडरCalendar है । ईआरए स्थिरांक: आप सामान्य युग (बीसी - ईसा से पहले) या सामान्य युग (एडी - एनो डोमिनी) से पहले की तारीख का संकेत दे सकते हैं। आइए यह सब उदाहरण के साथ देखें। आइए 25 जनवरी, 2017 की तारीख के साथ एक वस्तु बनाएँ: calendar

public static void main(String[] args) {

  Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
कक्षा में Calendar(साथ ही Dateउस मामले के लिए कक्षा), महीने शून्य से शुरू होते हैं , इसलिए हम संख्या 0 को दूसरे तर्क के रूप में पास करते हैं। कक्षा के साथ काम करते समय Calendar, यह समझना महत्वपूर्ण है कि यह केवल एक कैलेंडर है , कोई व्यक्तिगत तिथि नहीं है। समय में खोया कैसे नहीं: दिनांक समय और कैलेंडर - 3 एक तिथि केवल कुछ संख्याएँ होती हैं जो एक विशिष्ट समय अंतराल का संकेत देती हैं। एक कैलेंडर एक संपूर्ण प्रणाली है जो आपको तिथियों के साथ बहुत कुछ करने देती है। :) यदि आप वस्तु को प्रदर्शित करने का प्रयास करते हैं तो यह स्पष्ट रूप से स्पष्ट है Calendar: आउटपुट: java.util.GregorianCalendar [समय =?, areFieldsSet = गलत, areAllFieldsSet = झूठा, उदार = सत्य, क्षेत्र = सूर्य। util.calendar.ZoneInfo [id = "यूरोप/लंदन", ऑफसेट = 0, dstSavings = 0, useDaylight = झूठा, संक्रमण = 79, अंतिम नियम = शून्य], पहला दिन का सप्ताह = 2, न्यूनतम दिन पहले सप्ताह = 1, युग =?, वर्ष = 2017, महीने = 0, WEEK_OF_YEAR =?, WEEK_OF_MONTH =?, DAY_OF_MONTH = 25, DAY_OF_YEAR =?, DAY_OF_WEEK =? ,DAY_OF_WEEK_IN_MONTH=?, AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?] देखें आपको कितनी जानकारी मिलती है ! एक कैलेंडर में गुणों का एक गुच्छा होता है जो एक सामान्य तिथि में नहीं होता है, और वे सभी प्रदर्शित होते हैं (इस प्रकारtoString()में विधि काम करती हैCalendar)। यदि आपको केवल कैलेंडर से एक साधारण तिथि, यानी एकDateवस्तु प्राप्त करने की आवश्यकता है, तो इसका उपयोग करेंCalendar.getTime()विधि (नाम सबसे तार्किक नहीं है, लेकिन आप क्या कर सकते हैं?):

public static void main(String[] args) {

   Calendar calendar = new GregorianCalendar(2017, 0 , 25);
   Date date = calendar.getTime();
   System.out.println(date);
}
आउटपुट: Wed Jan 25 00:00:00 GMT 2017 अब हमने कैलेंडर ले लिया है और "इसे कम कर दिया है" एक सामान्य तिथि के लिए। आगे चलते हैं। महीनों को उनकी संख्या से निर्दिष्ट करने के अतिरिक्त, आप Calendarकक्षा के स्थिर फ़ील्ड मानों का उपयोग कर सकते हैं । ये स्थिरांक Calendarएक पूर्व निर्धारित मान वाले वर्ग के स्थिर क्षेत्र हैं जिन्हें बदला नहीं जा सकता। यह वास्तव में एक बेहतर विकल्प है, क्योंकि इनका उपयोग करने से आपके कोड की पठनीयता में सुधार होता है।

public static void main(String[] args) {
   GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Calendar.JANUARY उन स्थिरांकों में से एक है जो वर्ष के महीनों का प्रतिनिधित्व करते हैं। इन नामित स्थिरांकों का उपयोग करते हुए, कोई भी नहीं भूलेगा, उदाहरण के लिए, संख्या 3 का मतलब अप्रैल है, न कि तीसरा महीना, जिसे हम मार्च कहना पसंद करते हैं। बस Calendar.APRIL लिखें और आपका काम हो गया। :) सभी कैलेंडर फ़ील्ड (संख्या, महीना, मिनट, सेकंड, आदि)set()विधि का उपयोग करके अलग से निर्दिष्ट किए जा सकते हैं। यह विधि बहुत सुविधाजनक है, क्योंकिCalendarकक्षा में प्रत्येक क्षेत्र के लिए एक स्थिरांक होता है, और परिणामी कोड को पढ़ना बहुत आसान होता है। पिछले उदाहरण में, हमने एक तिथि बनाई, लेकिन उसके लिए कोई समय निर्धारित नहीं किया। 19:42:12 का समय निर्धारित करते हैं

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar();
   calendar.set(Calendar.YEAR, 2017);
   calendar.set(Calendar.MONTH, 0);
   calendar.set(Calendar.DAY_OF_MONTH, 25);
   calendar.set(Calendar.HOUR_OF_DAY, 19);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   System.out.println(calendar.getTime());
}
आउटपुट: Wed Jan 25 19:42:12 GMT 2017 हम set()मेथड को कॉल करते हैं, एक कॉन्स्टेंट पास करते हुए (जिस फील्ड को हम बदलना चाहते हैं उसके आधार पर) और फील्ड के लिए नया वैल्यू। यह पता चला है कि यह set()विधि एक प्रकार का "सुपर-सेटर" है जो जानता है कि मूल्य को केवल एक क्षेत्र के लिए नहीं, बल्कि कई क्षेत्रों के लिए कैसे निर्धारित किया जाए। :) वर्ग मूल्यों को जोड़ने और घटाने के लिए विधि का Calendarउपयोग करता है । add()आप उस क्षेत्र में गुजरते हैं जिसे आप बदलना चाहते हैं, और एक संख्या (वास्तव में आप वर्तमान मूल्य से कितना जोड़ना/घटाना चाहते हैं)। उदाहरण के लिए, हमारे द्वारा बनाई गई तारीख से 2 महीने पहले की तारीख प्राप्त करें:

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 19);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.add(Calendar.MONTH, -2); // To subtract, pass a negative number
   System.out.println(calendar.getTime());
}
आउटपुट: शुक्र नवम्बर 25 19:42:12 GMT 2016 बहुत अच्छा! हमें 2 महीने पहले तारीख मिली थी। इससे न केवल महीने में बदलाव हुआ: वर्ष भी 2017 से 2016 में बदल गया। बेशक, तारीखों को परिवर्तित करते समय, वर्तमान वर्ष की गणना स्वचालित रूप से की जाती है, इसके लिए आपको इसे मैन्युअल रूप से ट्रैक करने की आवश्यकता नहीं होती है। लेकिन अगर किसी कारण से आपको इस व्यवहार को अक्षम करने की आवश्यकता है, तो आप ऐसा कर सकते हैं। विधि शेष मूल्यों को प्रभावित किए बिनाroll() मूल्यों को जोड़ और घटा सकती है । उदाहरण के लिए, इस तरह:

public static void main(String[] args) {
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.roll(Calendar.MONTH, -2);
   System.out.println(calendar.getTime());
}
हमने ठीक वैसा ही किया जैसा पिछले उदाहरण में किया था: हमने वर्तमान तिथि से 2 महीने लिए। लेकिन अब कोड कुछ अलग करता है: महीना जनवरी से नवंबर में बदल गया है, लेकिन साल अपरिवर्तित रहता है- 2017! आउटपुट: शनि 25 नवंबर 10:42:12 जीएमटी 2017 साथ चल रहा है। जैसा कि हमने ऊपर कहा, हम सभी Calendarक्षेत्रों को अलग-अलग प्राप्त कर सकते हैं। हम इसे get()विधि से करते हैं:

public static void main(String[] args) {
   GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   System.out.println("Year: " + calendar.get(Calendar.YEAR));
   System.out.println("Month: " + calendar.get(Calendar.MONTH));
   System.out.println("Week in the month: " + calendar.get(Calendar.WEEK_OF_MONTH));// Week in this month?

   System.out.println("Day: " + calendar.get(Calendar.DAY_OF_MONTH));

   System.out.println("Hours: " + calendar.get(Calendar.HOUR));
   System.out.println("Minutes: " + calendar.get(Calendar.MINUTE));
   System.out.println("Seconds: " + calendar.get(Calendar.SECOND));
   System.out.println("Milliseconds: " + calendar.get(Calendar.MILLISECOND));

}
आउटपुट: वर्ष: 2017 महीना: 0 महीने में सप्ताह: 5 दिन: 25 घंटे: 10 मिनट: 42 सेकंड: 12 मिलीसेकंड: 0 इसलिए, कक्षा के "सुपर-सेटर" के अलावा Calendar, "सुपर-गेटर" भी है "। :) बेशक, इस वर्ग का एक और दिलचस्प पहलू युगों के साथ काम कर रहा है। एक "BC" तिथि बनाने के लिए, आपको Calendar.ERA फ़ील्ड का उपयोग करने की आवश्यकता होगी। उदाहरण के लिए, आइए कनाई की लड़ाई के लिए एक तिथि बनाएं, जहां हैनिबल ने रोमन सेना को हराया था। यह 2 अगस्त, 216 ई.पू. को हुआ था:

public static void main(String[] args) {
   GregorianCalendar cannae = new GregorianCalendar(216, Calendar.AUGUST, 2);
   cannae.set(Calendar.ERA, GregorianCalendar.BC);

   DateFormat df = new SimpleDateFormat("MMM dd, yyy GG");
   System.out.println(df.format(cannae.getTime()));
}
यहां हमने SimpleDateFormatतारीख को एक प्रारूप में प्रिंट करने के लिए कक्षा का उपयोग किया जो हमारे लिए समझना आसान है ("जीजी" अक्षर इंगित करते हैं कि हम चाहते हैं कि युग प्रदर्शित हो)। आउटपुट: अगस्त 02, 216 ई.पू. कक्षा Calendarमें कई और विधियाँ और स्थिरांक हैं। आप उनके बारे में दस्तावेज़ीकरण में पढ़ सकते हैं । अगर आपको यह दिनांक प्रारूप पसंद नहीं है तो Sat Nov 25 10:42:12 GMT 2017 तो आप SimpleDateFormatइसे आसानी से बनाने के लिए उपयोग कर सकते हैं जो आप इसे बनाना चाहते हैं।

public static void main(String[] args) {

   SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
   Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
   calendar.set(Calendar.HOUR, 10);
   calendar.set(Calendar.MINUTE, 42);
   calendar.set(Calendar.SECOND, 12);

   calendar.roll(Calendar.MONTH, -2);
   System.out.println(dateFormat.format(calendar.getTime()));
}
आउटपुट: शनिवार, 25 नवंबर, 2017 यह बहुत बेहतर है, है ना? :)
टिप्पणियां
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION