java - जावा तिथि बनाम कैलेंडर
date calendar (8)
tl; डॉ
Date
औरCalendar
आसपास वर्तमान "सर्वोत्तम अभ्यास" की सलाह दें
Calendar
परDate
का हमेशा अनुकूल होना सर्वोत्तम है
पूरी तरह से इन विरासत वर्गों से बचें । इसके बजाय java.time कक्षाओं का प्रयोग करें।
- UTC में एक पल के लिए,
Instant
उपयोग करें
(Date
के आधुनिक समतुल्य) - किसी विशेष समय क्षेत्र में एक पल के लिए,
ZonedDateTime
उपयोगZonedDateTime
(GregorianCalendar
के आधुनिक समतुल्य) - एक विशेष offset-from-UTC में एक पल के लिए,
OffsetDateTime
उपयोगOffsetDateTime
(विरासत कक्षाओं में कोई समकक्ष नहीं) - अज्ञात समय क्षेत्र या ऑफसेट के साथ डेट-टाइम (एक पल नहीं) के लिए,
LocalDateTime
उपयोगLocalDateTime
(विरासत कक्षाओं में कोई समकक्ष नहीं)
विवरण
ऑर्टोमाला लोकनी का उत्तर परेशानी पुरानी विरासत दिनांक-समय कक्षाओं ( Date
, Calendar
इत्यादि) की बजाय आधुनिक java.time कक्षाओं का उपयोग करने का सुझाव देने का अधिकार है। लेकिन वह उत्तर गलत वर्ग को बराबर समझाता है (उस उत्तर पर मेरी टिप्पणी देखें)।
जावा.टाइम का उपयोग करना
जावा.टाइम कक्षाएं लीगेसी डेट-टाइम कक्षाओं, रात-दर-दिन अंतर पर एक बड़ा सुधार है। पुरानी कक्षाएं खराब-डिजाइन, भ्रमित और परेशानी हैं। जब भी संभव हो, आपको पुरानी कक्षाओं से बचना चाहिए। लेकिन जब आपको पुराने / नए में कनवर्ट करने की आवश्यकता होती है, तो आप पुरानी कक्षाओं में नए तरीकों को जोड़कर ऐसा कर सकते हैं।
रूपांतरण पर अधिक जानकारी के लिए, मेरे उत्तर और निफ्टी आरेख को किसी अन्य प्रश्न पर देखें, java.util.Date को "java.time" प्रकार में बदलें? ।
खोज स्टैक ओवरफ़्लो java.time का उपयोग करने पर कई सैकड़ों उदाहरण प्रश्न और उत्तर देता है। लेकिन यहां एक त्वरित सारांश है।
Instant
एक Instant
साथ वर्तमान पल प्राप्त करें। Instant
क्लास UTC में टाइमलाइन पर nanoseconds संकल्प के साथ एक पल का प्रतिनिधित्व करता है (दशमलव अंश के नौ (9) अंकों तक)।
Instant instant = Instant.now();
ZonedDateTime
किसी विशेष क्षेत्र के वॉल-घड़ी समय के लेंस के माध्यम से उसी एक साथ पल को देखने के लिए, ZoneId
प्राप्त करने के लिए एक समय क्षेत्र ( ZoneId
) ZonedDateTime
।
समय क्षेत्र
continent/region
, जैसे America/Montreal
, Africa/Casablanca
, या Pacific/Auckland
के प्रारूप में उचित समय क्षेत्र का नाम निर्दिष्ट करें। EST
या IST
जैसे 3-4 अक्षर संक्षेप का कभी भी उपयोग न करें क्योंकि वे सही समय क्षेत्र नहीं हैं, मानकीकृत नहीं हैं, और यहां तक कि अनूठा (!) भी नहीं।
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone();
ओफ़्सेट
एक समय क्षेत्र एक offset-from-UTC ऑफ offset-from-UTC में परिवर्तन का इतिहास है। लेकिन कभी-कभी आपको पूर्ण क्षेत्र के बिना केवल ऑफसेट दिया जाता है। उस स्थिति में, OffsetDateTime
क्लास का उपयोग करें।
ZoneOffset offset = ZoneOffset.parse( "+05:30" );
OffsetDateTime odt = instant.atOffset( offset );
एक समय क्षेत्र का उपयोग केवल ऑफसेट के उपयोग पर बेहतर है।
LocalDateTime
स्थानीय में "स्थानीय" Local…
कक्षाओं का अर्थ किसी भी इलाके का है, न कि एक विशेष इलाके। तो नाम काउंटर-सहज हो सकता है।
LocalDateTime
, LocalDate
, और LocalTime
जानबूझकर ऑफ़सेट या समय क्षेत्र के बारे में कोई जानकारी नहीं है। इसलिए वे वास्तविक क्षणों का प्रतिनिधित्व नहीं करते हैं, वे समयरेखा पर अंक नहीं हैं। जब संदेह या भ्रम में, ZonedDateTime
बजाय ZonedDateTime
उपयोग करें। अधिक चर्चा के लिए खोज स्टैक ओवरफ़्लो खोजें।
स्ट्रिंग्स
डेट-टाइम ऑब्जेक्ट्स को स्ट्रिंग्स के साथ विवादित न करें जो उनके मूल्य का प्रतिनिधित्व करते हैं। आप डेट-टाइम ऑब्जेक्ट प्राप्त करने के लिए स्ट्रिंग को पार्स कर सकते हैं, और आप डेट-टाइम ऑब्जेक्ट से स्ट्रिंग जेनरेट कर सकते हैं। लेकिन स्ट्रिंग कभी भी डेट-टाइम नहीं है।
मानक आईएसओ 8601 स्वरूपों के बारे में जानें, जो जावा.टाइम कक्षाओं में डिफ़ॉल्ट रूप से उपयोग किए जाते हैं।
जावा के बारे में
java.time फ्रेमवर्क जावा 8 और बाद में बनाया गया है। ये कक्षाएं परेशानी पुरानी legacy दिनांक-समय कक्षाओं जैसे java.util.Date
, Calendar
, और SimpleDateFormat
।
Joda-Time प्रोजेक्ट, अब रखरखाव मोड में , java.time कक्षाओं में माइग्रेशन की सलाह देता है।
अधिक जानने के लिए, ओरेकल ट्यूटोरियल देखें। और कई उदाहरणों और स्पष्टीकरणों के लिए स्टैक ओवरफ़्लो खोजें। विशिष्टता JSR-310 ।
जेडीबीसी 4.2 या उसके बाद के संस्करण के साथ एक जेडीबीसी ड्राइवर का अनुपालन करते हुए, आप java.time ऑब्जेक्ट्स को सीधे अपने डेटाबेस के साथ बदल सकते हैं। तारों की कोई ज़रूरत नहीं है और न ही java.sql। * कक्षाएं।
जावा.टाइम कक्षाएं कहां प्राप्त करें?
- जावा एसई 8 , जावा एसई 9 , और बाद में
- निर्मित।
- एक बंडल कार्यान्वयन के साथ मानक जावा एपीआई का हिस्सा।
- जावा 9 कुछ मामूली विशेषताओं और फिक्सेस जोड़ता है।
- जावा एसई 6 और जावा एसई 7
- जावाटाइम की अधिकांश कार्यक्षमता को ThreeTen-Backport में जावा 6 और 7 में बैक-पोर्ट किया गया है।
- Android
- जावा.टाइम कक्षाओं के एंड्रॉइड बंडल कार्यान्वयन के बाद के संस्करण।
- पहले एंड्रॉइड के लिए, ThreeTenABP प्रोजेक्ट थ्रीटेन-बैकपोर्ट (ऊपर उल्लिखित) को अपनाने वाला है । देखें थ्रीटेबैप का उपयोग कैसे करें ...।
ThreeTen-Extra प्रोजेक्ट अतिरिक्त कक्षाओं के साथ जावा.टाइम बढ़ाता है। यह परियोजना java.time के संभावित भविष्य के जोड़ों के लिए एक सिद्ध भूमि है। आपको यहां कुछ उपयोगी कक्षाएं मिल सकती हैं जैसे Interval
, YearWeek
, YearQuarter
, more ।
https://code.i-harness.com
क्या कोई व्यक्ति Date
और Calendar
प्रकारों के आसपास वर्तमान "सर्वोत्तम अभ्यास" की सलाह दे सकता है।
नए कोड लिखते समय, क्या हमेशा Calendar
से अधिक Date
पक्ष लेना सबसे अच्छा होता है, या ऐसी परिस्थितियां होती हैं जहां Date
अधिक उचित डेटाटाइप होती है?
जावा 8 के साथ, नया जावा.टाइम पैकेज इस्तेमाल किया जाना चाहिए।
ऑब्जेक्ट्स अपरिवर्तनीय हैं, समय क्षेत्र और दिन की हल्की बचत को ध्यान में रखा जाता है।
आप पुराने java.util.Date
ऑब्जेक्ट से ZonedDateTime
ऑब्जेक्ट बना सकते हैं:
Date date = new Date();
ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
तारीख फिर से विकसित की जानी चाहिए। एक लंबे अंतराल होने के बजाय, इसे अलग-अलग क्षेत्रों के रूप में वर्ष, महीना, तिथि, घंटा, मिनट, दूसरा होना चाहिए। कैलेंडर और समय क्षेत्र को संग्रहीत करना भी अच्छा हो सकता है, इस तिथि से जुड़ा हुआ है।
हमारी प्राकृतिक वार्तालाप में, अगर 1 नवंबर, 2013 को 1 बजे एनवाई टाइम में नियुक्ति की स्थापना की जाती है, तो यह डेटटाइम है। यह कैलेंडर नहीं है। तो हम जावा में इस तरह से बातचीत करने में सक्षम होना चाहिए।
जब दिनांक एक लंबे पूर्णांक के रूप में संग्रहीत किया जाता है (1 जनवरी 1 9 70 या कुछ के बाद मिली सेकंड का), इसकी वर्तमान तिथि की गणना कैलेंडर पर निर्भर करती है। अलग-अलग कैलेंडर अलग-अलग तारीख देंगे। यह एक पूर्ण समय देने की संभावना से है (उदाहरण के लिए बिग बैंग के बाद 1 ट्रिलियन सेकंड)। लेकिन अक्सर हमें वार्तालाप के सुविधाजनक तरीके की भी आवश्यकता होती है, जैसे ऑब्जेक्ट एन्सेप्लेटिंग वर्ष, महीने इत्यादि।
मुझे आश्चर्य है कि जावा में इन 2 उद्देश्यों को सुलझाने के लिए नई प्रगति है या नहीं। शायद मेरा जावा ज्ञान बहुत पुराना है।
तिथि एक सरल वर्ग है और मुख्य रूप से पिछड़े संगतता कारणों के लिए है। यदि आपको विशेष तिथियां सेट करने या अंकगणित करने की आवश्यकता है, तो कैलेंडर का उपयोग करें। कैलेंडर स्थानीयकरण को भी संभालते हैं। तिथि की पिछली तारीख मैनिपुलेशन फ़ंक्शंस को तब से बहिष्कृत कर दिया गया है।
निजी तौर पर जब मैं कोई विकल्प होता हूं तो मुझे मिलीसेकंड में लंबे समय तक (या लंबे, उचित के रूप में) या कैलेंडर का उपयोग करना पड़ता है।
दिनांक और कैलेंडर दोनों उत्परिवर्तनीय हैं, जो किसी एपीआई में उपयोग करते समय समस्याएं प्रस्तुत करते हैं।
पार्टी में थोड़ी देर हो चुकी है, लेकिन जावा के पास जेडीके 8 में एक नया डेट टाइम एपीआई है। आप अपने जेडीके संस्करण को अपग्रेड करना और मानक को गले लगा सकते हैं। कोई और गन्दा तारीख / कैलेंडर नहीं, कोई और तृतीय पक्ष जार नहीं।
बीटीडब्ल्यू "डेट" को आम तौर पर "अप्रचलित / बहिष्कृत" के रूप में टैग किया जाता है (मुझे बिल्कुल पता नहीं क्यों है) - इसके बारे में कुछ लिखा गया है जावा: दिनांक निर्माता का बहिष्कार क्यों किया गया है, और इसके बजाय मैं इसका उपयोग कैसे करूं?
ऐसा लगता है कि यह नई तारीख (int वर्ष, int month, int day) के माध्यम से केवल कन्स्ट्रक्टर की समस्या है, अनुशंसित तरीका कैलेंडर के माध्यम से है और अलग-अलग पैरा सेट करता है .. ( कैलेंडर cal = calendar.getInstance (); )
यदि संभव हो तो मैं आम तौर पर तारीख का उपयोग करता हूं। हालांकि यह उत्परिवर्तनीय है, म्यूटेटर वास्तव में बहिष्कृत हैं। अंत में यह मूल रूप से एक लंबे समय तक लपेटता है जो दिनांक / समय का प्रतिनिधित्व करेगा। इसके विपरीत, अगर मैं मूल्यों में हेरफेर करना चाहता हूं तो मैं कैलेंडर का उपयोग करूंगा।
आप इस बारे में सोच सकते हैं: आप केवल स्ट्रिंगबफर का उपयोग करते हैं जब आपको स्ट्रिंग्स की आवश्यकता होती है जिसे आप आसानी से जोड़ सकते हैं और फिर उन्हें स्ट्रिंग () विधि का उपयोग करके स्ट्रिंग्स में परिवर्तित कर सकते हैं। इसी तरह, अगर मैं अस्थायी डेटा में हेरफेर करने की ज़रूरत है तो मैं केवल कैलेंडर का उपयोग करता हूं।
सर्वोत्तम अभ्यास के लिए, मैं डोमेन मॉडल के बाहर जितना संभव हो सके अपरिवर्तनीय वस्तुओं का उपयोग करता हूं। यह किसी भी साइड इफेक्ट्स की संभावनाओं को काफी कम करता है और यह आपके लिए जुनीट टेस्ट के बजाय कंपाइलर द्वारा किया जाता है। आप अपनी कक्षा में निजी अंतिम फ़ील्ड बनाकर इस तकनीक का उपयोग करते हैं।
और स्ट्रिंगबफर समरूपता पर वापस आ रहा है। यहां कुछ कोड दिया गया है जो आपको दिखाता है कि कैलेंडर और दिनांक के बीच कैसे परिवर्तित करें
String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String
// immutable date with hard coded format. If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");
// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// mutate the value
cal.add(Calendar.YEAR, 1);
// convert back to Date
Date newDate = cal.getTime();
//
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);
Date
को समय पर अपरिवर्तनीय बिंदु के रूप में उपयोग किया जाना चाहिए; Calendar
म्यूटेबल हैं, और अंतिम तिथि के साथ आने के लिए आपको अन्य कक्षाओं के साथ सहयोग करने की आवश्यकता होने पर चारों ओर पारित किया जा सकता है। उन्हें String
और String
समान StringBuilder
और आप समझेंगे कि मुझे कैसे लगता है कि उनका उपयोग किया जाना चाहिए।
(और हाँ, मुझे पता है कि तारीख वास्तव में तकनीकी रूप से अपरिवर्तनीय नहीं है, लेकिन इरादा यह है कि इसे उत्परिवर्तनीय नहीं होना चाहिए, और यदि कुछ भी बहिष्कृत तरीकों को कॉल नहीं करता है तो ऐसा होता है।)