2009-12-28 15 views
76

अक्सर जावा Date और अन्य दिनांक-समय-संबंधित कक्षाओं पर नकारात्मक प्रतिक्रिया प्राप्त होती है। एक .NET डेवलपर होने के नाते, मैं पूरी तरह से (उन्हें उपयोग किए बिना) समझ नहीं सकता, वास्तव में उनके साथ क्या गलत है।जावा तिथि और समय API के साथ क्या गलत है?

क्या कोई इस पर कुछ प्रकाश डाल सकता है?

+0

यह भी देखें: [जावा तिथियां - उपयोग करने के लिए सही वर्ग क्या है?] (Https://stackoverflow.com/q/8511430/642706) –

उत्तर

107

आह, जावा Date कक्षा। शायद किसी भी भाषा में कहीं भी कुछ नहीं करने के सर्वोत्तम उदाहरणों में से एक। मै कहाँ से शुरू करू?

जावाडोक पढ़ने से किसी को यह सोचने का मौका मिल सकता है कि डेवलपर्स को वास्तव में कुछ अच्छे विचार मिलते हैं। यह UTC और GMT के बीच के अंतर के बारे में इस तथ्य के बावजूद है कि दोनों के बीच का अंतर मूल रूप से छलांग लगाता है (जो prettyrarely होता है)।

हालांकि, डिजाइन निर्णय वास्तव में एक अच्छी तरह से डिज़ाइन किए गए एपीआई होने के किसी भी विचार को बर्बाद करने के लिए तैयार हैं। यहाँ पसंदीदा गलतियों में से कुछ हैं: सहस्राब्दी के पिछले दशक में तैयार किया जा रहा बावजूद

  • , यह 1900 के बाद से दो अंकों के रूप में साल दर वहाँ सचमुच में हैं 1900+ (या 1900-) कर समाधान के लाखों इस मौलिक निर्णय के परिणामस्वरूप जावा दुनिया।
  • महीनों को शून्य अनुक्रमित किया गया है, जिसमें अदभुत महीनों के शानदार असामान्य मामले को पूरा करने के लिए और तेरह तत्व सरणी के साथ नहीं रहना है, जिनमें से पहला null है। नतीजतन, हमारे पास 0..11 है (और आज वर्ष 109 का महीना 11 है)। स्ट्रिंग में कनवर्ट करने के लिए महीनों में ++ और समान संख्याएं हैं।
  • वे mutable हैं। नतीजतन, जब भी आप एक तारीख वापस देना चाहते हैं (कहें, एक उदाहरण संरचना के रूप में) आपको तारीख की वस्तु के बजाय उस तारीख का क्लोन वापस करने की आवश्यकता है (अन्यथा, लोग आपकी संरचना को बदल सकते हैं)।
  • Calendar, इसे 'ठीक करने' के लिए डिज़ाइन किया गया है, वास्तव में वही गलतियों को बनाता है। वे अभी भी mutable हैं।
  • DateDateTime का प्रतिनिधित्व करता है, लेकिन एसक्यूएल भूमि में उन लोगों को स्थगित करने के लिए, एक और उपclass java.sql.Date है, जो एक दिन का प्रतिनिधित्व करता है (हालांकि इसके साथ जुड़े समय क्षेत्र के बिना)।
  • एक Date के साथ जुड़े नहीं TimeZone रों रहे हैं, और इसलिए (जैसे कि एक 'पूरे दिन' के रूप में) पर्वतमाला अक्सर एक आधी रात-आधी रात (अक्सर कुछ मनमाने ढंग से समय क्षेत्र के अनुसार)

अंत के रूप में प्रतिनिधित्व कर रहे हैं, यह लायक है यह नोट करते हुए कि लीप सेकंड आमतौर पर एक अच्छी प्रणाली घड़ी के खिलाफ खुद को सही करते हैं जिसे एक घंटे के भीतर एनटीपी के साथ अपडेट किया जाता है (नीचे दिए गए लिंक देखें)। एक प्रणाली का मौका अभी भी दो लीप सेकंड (हर छह महीने न्यूनतम, व्यावहारिक रूप से हर कुछ वर्षों) के परिचय में चल रहा है और चल रहा है, विशेष रूप से इस तथ्य पर विचार करना कि आपको समय-समय पर अपने कोड के नए संस्करणों को फिर से तैनात करना है । यहां तक ​​कि एक गतिशील भाषा का उपयोग करना जो कक्षाओं को पुन: उत्पन्न करता है या WAR इंजन की तरह कुछ कक्षा स्थान को प्रदूषित करेगा और अंततः परमजन से बाहर चला जाएगा।

+0

+1, धन्यवाद लिंक के लिए। – Reddy

11

मैं आपके लिए महसूस करता हूं ... एक पूर्व .NET प्रोग्रामर के रूप में, मैंने एक ही प्रश्न पूछा, .NET (टाइमपैन, ऑपरेटर अधिभार) में समय एपीआई बहुत सुविधाजनक है।

सबसे पहले, एक विशिष्ट तिथि बनाने के लिए, आप या तो एक बहिष्कृत API, या का उपयोग करें:

Calendar c = Calendar.getInstance(); 
c.set(2000, 31, 12) 

एक दिन घटाना करने के लिए आप

Date firstDate = ... 
Calendar c = Calendar.getInstance(); 
c.setTime(fistDate); 
c.add(Calendar.DATE,-1); 
Date dayAgo = c.getTime(); 

या बुरा

Date d = new Date(); 
Date d2 = new Date(d.getTime() - 1000*60*60*24); 
की तरह बुराई बातें करते हैं

यह पता लगाने के लिए कि दो तिथियों (दिनों/सप्ताह/महीनों में) के बीच कितना समय बीत चुका है ... यह भी बदतर हो जाता है

अपाचे से

हालांकि DateUtils (org.apache.commons.lang.time.DateUtils) कुछ सुविधाजनक तरीके प्रदान करते हैं और मैं का उपयोग कर केवल उन्हें हाल ही में

Brabster के रूप में लिखा था, Joda समय भी एक अच्छा बाहरी पुस्तकालय है अपने आप को पाया है, लेकिन अपाचे लगता है और अधिक "आम" से कुछ और ...

+0

कृपया हमें बताएं कि ऐसा कैसे करें ("पता लगाएं कि कितना दो तिथियों के बीच समय बीत गया ")! –

+0

मेरी इच्छा है कि मुझे एक आसान तरीका पता था ... लीप साल, अजीब महीनों और vlolatile दिनों सहित ... –

+10

मास्टर जोडा (समय), बाहर निकलना, आपको चाहिए। –

25
  • दिनांक उदाहरण mutable है, जो लगभग हमेशा असुविधाजनक होता है।
  • उनके पास एक डबल प्रकृति है। वे एक टाइमस्टैम्प और कैलेंडर तिथि दोनों का प्रतिनिधित्व करते हैं। यह पता चलता है कि तारीखों पर गणना करते समय यह समस्याग्रस्त है।
  • कैलेंडर डेटा के संख्यात्मक प्रतिनिधित्व कई मामलों में काउंटर-अंतर्ज्ञानी हैं। उदाहरण के लिए: getMonth() शून्य-आधारित है, getYear() 1 9 00-आधारित है (यानी, वर्ष 200 9 को 109 के रूप में दर्शाया गया है)।
  • वे Date कक्षा से आपकी बहुत सारी कार्यक्षमता खो रहे हैं।
3

मुझे ईमानदार होने के लिए जावा की दिनांक API उपयोग योग्य लगता है। वर्बोज़िटी से संबंधित अधिकांश मुद्दों को मैंने देखा और सुना है, कुछ कक्षाओं को उपयोगी बनाने के लिए कई वर्गों को शामिल करने की आवश्यकता है (Calendar, Date, DateFormat/SimpleDateFormat) और getDayOfWeek() जैसे सरल एक्सेसर्स की कमी।

Joda Time जावा में एक अच्छी तरह से सम्मानित वैकल्पिक एपीआई है, और क्यों जोडा समय अनुभाग में यह कुछ और तर्क देता है कि यह एक व्यवहार्य विकल्प क्यों है जो ब्याज का हो सकता है।

37

JSR 310, जो जावा 8 में java.time के साथ पुरानी तिथि-समय वर्गों का स्थान ले लिया, जो अपने आप original JSR में सही ठहराते हैं इस प्रकार है:

2,5 जावा समुदाय की क्या जरूरत प्रस्तावित विनिर्देश द्वारा संबोधित किया जाएगा?

वर्तमान में जावा एसई में दो अलग दिनांक और समय एपीआई हैं - java.util.Date और java.util.Calendar। दोनों एपीआई को वेब डेवलपर्स और फ़ोरम पर जावा डेवलपर्स द्वारा लगातार उपयोग के रूप में वर्णित किया गया है। विशेष रूप से, दोनों महीनों के लिए शून्य-अनुक्रमणिका का उपयोग करते हैं, जो कई बग का कारण है। कैलेंडर को से पर कई बग और प्रदर्शन समस्याएं भी हुई हैं, मुख्य रूप से को अपने राज्य को दो अलग-अलग तरीकों से को संग्रहीत करने के कारण।

एक क्लासिक बग (4639407) कैलेंडर ऑब्जेक्ट में बनाई जाने वाली कुछ तिथियों को रोका गया। कोड का अनुक्रम लिखा जा सकता है जो कुछ वर्षों में दिनांक बना सकता है लेकिन अन्य में नहीं, कुछ उपयोगकर्ताओं को उनकी सही जन्म तिथियों को दर्ज करने से रोकने का प्रभाव पड़ता है। कैलेंडर क्लास केवल ग्रीष्म ऋतु में एक घंटे की डेलाइट बचत समय लाभ की अनुमति देता है, जब ऐतिहासिक रूप से यह और द्वितीय विश्व युद्ध के समय के आसपास 2 घंटे था। हालांकि यह बग है, अगर भविष्य में किसी बिंदु पर किसी देश ने भविष्य में प्लस के डेलाइट बचत समय लाभ को गर्मियों में तीन घंटे पेश करने का विकल्प चुना है, तो कैलेंडर क्लास फिर से टूटा जाएगा।

वर्तमान जावा एसई एपीआई भी बहु-थ्रेडेड वातावरण में पीड़ित है। अपरिवर्तनीय कक्षाएं को स्वाभाविक रूप से थ्रेड-सुरक्षित होने के रूप में जाना जाता है क्योंकि उनके राज्य परिवर्तित नहीं हो सकते हैं। हालांकि, दिनांक और कैलेंडर म्यूटेबल हैं, जिसके लिए क्लोनिंग और स्पष्ट रूप से थ्रेडिंग पर विचार करने के लिए प्रोग्रामर की आवश्यकता होती है। इसके अलावा, में थ्रेड-सुरक्षा की कमी डेटटाइमफॉर्मैट व्यापक रूप से ज्ञात नहीं है, और को कई कठिन कारणों का कारण रहा है जो थ्रेडिंग समस्याओं को ट्रैक करते हैं।

साथ ही वर्गों जावा SE datetime के लिए है के साथ समस्याओं, यह अन्य अवधारणाओं मॉडलिंग के लिए कोई कक्षाएं नहीं है। गैर-समय-क्षेत्र तिथियां या बार, अवधि, अवधि और अंतराल में जावा एसई में कोई वर्ग प्रतिनिधित्व नहीं है। नतीजतन, डेवलपर्स अक्सर समय की अवधि का प्रतिनिधित्व करने के लिए एक int का उपयोग करते हैं, जिसमें javadoc इकाई निर्दिष्ट करता है।

एक व्यापक तारीख और समय मॉडल की कमी भी कई आम संचालन जटिल काम की तुलना में वे होना चाहिए किया जा रहा है का परिणाम है। उदाहरण के लिए, की गणना दो तिथियों के बीच की संख्या पर विशेष रूप से कठिन समस्या है।

यह JSR एक पूरा दिनांक और समय मॉडल, दिनांक और समय (के साथ और समय क्षेत्रों के बिना), अवधि और समय अवधि, अंतराल, और पार्स स्वरूपण सहित की समस्या से निपटने के होंगे।

संबंधित मुद्दे