Java में `DateTimeFormatter` स्वरूपण पैटर्न कोड में` uuuu` बनाम `yyyy`?




parsing date-formatting (2)

कहानी संक्षिप्त में

  1. 99% उद्देश्यों के लिए आप एक सिक्का उछाल सकते हैं, इससे कोई फर्क नहीं पड़ेगा कि आप yyyy या uuuu उपयोग करते हैं (या आप 2-अंक वाले वर्ष के लिए yy या uu उपयोग करते हैं)।
  2. यह इस पर निर्भर करता है कि आप 1 सीई (1 ईस्वी) से एक साल पहले क्या होना चाहते हैं। मुद्दा यह है कि इस तरह के 99% कार्यक्रमों में कभी नहीं होगा।

दो अन्य उत्तरों ने पहले ही इस तथ्य को प्रस्तुत कर दिया है कि u कैसे और कैसे बहुत अच्छी तरह से काम करते हैं, लेकिन मुझे अभी भी लगा कि कुछ गायब है, इसलिए मैं थोड़ा और राय आधारित उत्तर का योगदान दे रहा हूं।

स्वरूपण के लिए

यह मानते हुए कि आप 1 CE से पहले एक साल के लिए प्रारूपित होने की उम्मीद नहीं करते हैं, सबसे अच्छी बात यह है कि आप इस धारणा की जांच करें और इसके टूटने की स्थिति में उचित रूप से प्रतिक्रिया करें। उदाहरण के लिए, परिस्थितियों और आवश्यकताओं के आधार पर, आप एक त्रुटि संदेश प्रिंट कर सकते हैं या एक अपवाद फेंक सकते हैं। एक बहुत नरम विफलता पथ इस मामले में y (युग का वर्ष) और G (युग) के साथ एक पैटर्न और सामान्य, वर्तमान युग के मामले में u या y साथ एक पैटर्न का उपयोग करने के लिए हो सकता है। ध्यान दें कि यदि आप वर्तमान तिथि या आपके कार्यक्रम को संकलित करने की तारीख को प्रिंट कर रहे हैं, तो आप सुनिश्चित कर सकते हैं कि यह आम युग में है और चेक को छोड़ने का विकल्प चुन सकता है।

पार्सिंग के लिए

कई (अधिकांश?) मामलों में पार्स करने का अर्थ यह भी है कि आपके इनपुट स्ट्रिंग जैसा दिखता है, इसकी कोई गारंटी नहीं है। आमतौर पर यह उपयोगकर्ता से या किसी अन्य सिस्टम से आता है। एक उदाहरण: एक तारीख स्ट्रिंग 2018-09-29 के रूप में आती है। यहां uuuu और yyyy बीच का चुनाव इस बात पर निर्भर होना चाहिए कि स्ट्रिंग के 0 या ऋणात्मक (जैसे 0000-08-17 या -012-11-13 ) वर्ष होने पर आप क्या करना चाहते हैं। यह मानते हुए कि यह एक त्रुटि होगी, तत्काल उत्तर है: इस मामले में एक अपवाद के क्रम में yyyy का उपयोग करें। अभी भी महीन: uuuu उपयोग करें और पार्स करने के बाद पार्स की गई तारीख की सीमा की जांच करें। बाद का दृष्टिकोण दोनों को एक बेहतर सत्यापन के लिए और एक सत्यापन त्रुटि के मामले में बेहतर त्रुटि संदेश के लिए अनुमति देता है।

विशेष मामला (पहले से ही मेनो होच्स्चिल्ड द्वारा उल्लिखित): यदि आपका फ़ॉर्मेटर सख्त रिज़ॉल्वर शैली का उपयोग करता है और इसमें G बिना y होता है, तो पार्सिंग हमेशा विफल रहेगा क्योंकि कड़ाई से बोलने वाला वर्ष युग के बिना अस्पष्ट है: 1950 का अर्थ 1950 हो सकता है या 1950 ईसा पूर्व (1950 ईसा पूर्व) । तो इस मामले में आपको u आवश्यकता u (या डिफ़ॉल्ट युग की आपूर्ति करना, यह एक DateTimeFormatterBuilder माध्यम से संभव है)।

लंबी कहानी फिर से छोटी

आपकी तिथियों की स्पष्ट सीमा की जांच, विशेष रूप से आपके वर्ष, अप्रत्याशित रूप से बहुत प्रारंभिक वर्षों को पकड़ने के लिए uuuu और yyyy बीच विकल्प पर भरोसा करने से बेहतर है।

DateTimeFormatter वर्ग प्रलेखन वर्ष के लिए अपने स्वरूपण कोड के बारे में कहता है:

यू साल 2004; 04

वर्ष 2004 के y वर्ष के; 04

...

वर्ष: अक्षरों की गिनती न्यूनतम क्षेत्र की चौड़ाई निर्धारित करती है जिसके नीचे पैडिंग का उपयोग किया जाता है। यदि अक्षरों की गिनती दो है, तो कम किए गए दो अंकों के फॉर्म का उपयोग किया जाता है। मुद्रण के लिए, यह सबसे सही दो अंकों का आउटपुट देता है। पार्सिंग के लिए, यह 2000 के आधार मूल्य का उपयोग करके पार्स करेगा, जिसके परिणामस्वरूप एक वर्ष में सीमा 2000 से 2099 तक सम्मिलित होगी। यदि अक्षरों की संख्या चार से कम है (लेकिन दो नहीं), तो संकेत केवल SignStyle.NORMAL के अनुसार नकारात्मक वर्षों के लिए आउटपुट है। अन्यथा, साइन आउटपुट आउटपुट है यदि पैड चौड़ाई से अधिक है, जैसा कि SignStyle.EXCEEDS_PAD के अनुसार।

"युग" का कोई अन्य उल्लेख नहीं है।

तो इन दो कोडों के बीच अंतर क्या है, u बनाम y , year बनाम year-of-era ?

मुझे जावा में दिनांक के साथ काम करते समय इस तरह के पैटर्न का उपयोग कैसे करना चाहिए uuuu-MM-dd और कब yyyy-MM-dd

ऐसा लगता है कि उदाहरण कोड उन लोगों द्वारा लिखे गए हैं जो uuuu उपयोग करते हैं, लेकिन क्यों?

अन्य स्वरूपण वर्गों जैसे कि विरासत SimpleDateFormat में केवल yyyy , इसलिए मुझे भ्रम है कि java.time इस युग को "युग के वर्ष" के लिए क्यों लाता है।


DateTimeFormatter लिए स्वरूपण और पार्सिंग के लिए javadoc अनुभाग पैटर्न में यह निम्नलिखित 3 प्रासंगिक प्रतीकों को सूचीबद्ध करता है:

Symbol  Meaning        Presentation  Examples
------  -------        ------------  -------
 G       era            text          AD; Anno Domini; A
 u       year           year          2004; 04
 y       year-of-era    year          2004; 04

तुलना के लिए, ये अन्य प्रतीक समझने में आसान हैं:

 D       day-of-year    number        189
 d       day-of-month   number        10
 E       day-of-week    text          Tue; Tuesday; T

day-of-week , day-of-month , और day-of-week का दिन स्पष्ट रूप से दिए गए दायरे (वर्ष, माह, सप्ताह) के भीतर का दिन होता है।

तो, year-of-era अर्थ दिए गए दायरे (युग) के भीतर वर्ष है, और इसके ठीक ऊपर era को AD एक उदाहरण मूल्य (पाठ्यक्रम के अन्य मूल्य BC ) के साथ दिखाया गया है।

year हस्ताक्षरित वर्ष है, जहां वर्ष 0 1 BC , वर्ष -1 2 BC , और आगे।

उदाहरण के लिए: जूलियस सीजर की हत्या कब की गई थी ?

  • 15 मार्च, 44 ईसा पूर्व (पैटर्न MMMM d, y GG का उपयोग करके)
  • 15 मार्च, -43 (पैटर्न MMMM d, u का उपयोग करके)

पाठ्यक्रम का अंतर केवल तभी होगा जब वर्ष शून्य या नकारात्मक हो, और चूंकि यह दुर्लभ है, ज्यादातर लोग परवाह नहीं करते हैं, भले ही उन्हें करना चाहिए।

निष्कर्ष: यदि आप y उपयोग करते हैं तो आपको G उपयोग करना चाहिए। चूंकि G का उपयोग शायद ही कभी किया जाता है, इसलिए सही वर्ष प्रतीक u नहीं है, अन्यथा एक गैर-सकारात्मक वर्ष गलत रूप से दिखाई देगा।

इसे रक्षात्मक प्रोग्रामिंग के रूप में जाना जाता है :

रक्षात्मक प्रोग्रामिंग अप्रत्याशित परिस्थितियों में सॉफ्टवेयर के एक टुकड़े के निरंतर कार्य को सुनिश्चित करने के उद्देश्य से रक्षात्मक डिजाइन का एक रूप है

ध्यान दें कि DateTimeFormatter SimpleDateFormat अनुरूप है:

Letter  Date or Time Component  Presentation  Examples
------  ----------------------  ------------  --------
G       Era designator          Text          AD
y       Year                    Year          1996; 96

नकारात्मक वर्ष हमेशा एक समस्या रही है, और उन्होंने अब इसे u जोड़कर तय किया है।





java-time