2015-10-05 25 views
9

दो तिथियों के बीच वर्षों की गणना करते समय, जहां दूसरी तारीख की गणना पहली बार की जाती है (यह एक सरल उदाहरण है जो मैं काम कर रहा हूं), LocalDate और Period एक वर्ष की गणना करने लगते हैं कुछ अलग ढंग से।एक लीप वर्ष से

उदाहरण के लिए,

LocalDate date = LocalDate.of(1996, 2, 29); 
LocalDate plusYear = date.plusYears(1); 
System.out.println(Period.between(date, plusYear).getYears()); 

जबकि

LocalDate date = LocalDate.of(1996, 3, 29); 
LocalDate plusYear = date.plusYears(1); 
System.out.println(Period.between(date, plusYear).getYears()); 

स्पष्ट होने के बावजूद एक साल, 0 के रूप में वर्षों कहा, पहले Period वापसी करते हुए दूसरे मामले रिटर्न 1

वहाँ इस के चारों ओर एक साफ रास्ता नहीं है?

+0

मुझे विश्वास है कि आपका उत्पादन कोड वास्तव में 1 वर्ष जोड़ नहीं रहा है और यह गिनने की कोशिश कर रहा है कि उसने कितने वर्षों को जोड़ा है। आप वास्तव में क्या हासिल करने की कोशिश कर रहे हैं? हमें वास्तविक इनपुट और अपेक्षित आउटपुट दें। – dotvav

+3

@ डॉटवव: दिया गया उदाहरण मुझे स्पष्ट रूप से स्पष्ट लगता है ... मुझे इसके साथ कुछ भी गलत नहीं दिख रहा है। –

+0

यदि आप वास्तव में शून्य के बजाय एक वर्ष का अंतर चाहते हैं तो बस वर्ष संख्याओं को घटाएं, किसी भी महीने या दिन-महीने-महीने में ध्यान न दें। –

उत्तर

3

यह सवाल एक दार्शनिक प्रकृति है और समय माप है और तिथि प्रारूप सम्मेलनों की तरह कुछ समस्याओं फैला है।

LocalDateISO 8601 तारीख विनिमय मानक के एक कार्यान्वयन है। जावा डॉक्टर को स्पष्ट रूप से कहा गया है कि इस वर्ग के समय का प्रतिनिधित्व नहीं करता है, लेकिन केवल मानक तिथि अंकन प्रदान करता है।

एपीआई अंकन पर ही केवल साधारण संचालन प्रदान करता है और सभी गणना माहवर्ष, या incrementing द्वारा किया जाता है, या दिवस किसी निश्चित तिथि के

दूसरे शब्दों में, LocalDate.plusYears() पर कॉल करते समय आप एक वर्ष के भीतर सटीक समय की तुलना में 365 दिनों के अवधारणात्मक वर्ष जोड़ रहे हैं।

यह दिन समय की सबसे कम इकाई है जो LocalDate द्वारा व्यक्त की गई तारीख में जोड़ सकता है।

मानव समझ में, दिनांक समय में एक पल नहीं है, लेकिन यह एक अवधि है।

यह 00h 00m 00 के दशक (...) के साथ शुरू होता है और 23h 59m 59s (...) के साथ खत्म।

LocalDate लेकिन बस के एक टपल के रूप में समय माप और मानव समय इकाइयों की अस्पष्टता की समस्याओं (घंटे, दिन, माह, और एक साल सभी विभिन्न लंबाई हो सकता है) और मॉडल तारीख अंकन से बचा जाता है :

(years, months within a year, days within a month)

युग की शुरुआत के बाद से गणना की।

इस व्याख्या में, यह समझ में आता है कि दिन तारीख को प्रभावित करने वाली सबसे छोटी इकाई है।

एक उदाहरण के रूप में निम्नलिखित:

LocalDate date = LocalDate.of(1996, 2, 29); 
LocalDate plusSecond = date.plus(1, ChronoUnit.SECONDS); 

रिटर्न

java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds 

... जो पता चलता है कि (परिशुद्धता प्राप्त करना हो या छोटी इकाइयों) LocalDate का उपयोग करने और जोड़ने सेकंड की संख्या है, तो आप आपके प्रश्न में सूचीबद्ध सीमा को दूर नहीं कर सका।

कार्यान्वयन को देखते हुए आपको LocalDate.plusYears() वर्षों को जोड़ने के बाद, resolvePreviousValid() पर कॉल करें। इस विधि तो लीप वर्ष के लिए जाँच करता है और निम्नलिखित तरीके से दिन क्षेत्र को संशोधित करता है:

day = Math.min(day, IsoChronology.INSTANCE.isLeapYear((long)year)?29:28);

दूसरे शब्दों में यह प्रभावी रूप से 1 दिन घटाकर यह सही करता है।

आप Year.length() जो भी वर्ष के लिए दिनों की संख्या देता है इस्तेमाल कर सकते हैं और लीप वर्ष के लिए वापस आ जाएगी। तो अगर आप कर सकता है:

LocalDate plusYear = date.plus(Year.of(date.getYear()).length(), ChronoUnit.DAYS); 

तुम अब भी कुछ विषमताएं निम्नलिखित में चलेगा (Year.length() करने के लिए कॉल संक्षिप्तता के लिए दिन की गिनती के साथ प्रतिस्थापित):

LocalDate date = LocalDate.of(1996, 2, 29); 
LocalDate plusYear = date.plus(365, ChronoUnit.DAYS); 
System.out.println(plusYear); 
Period between = Period.between(date, plusYear); 
System.out.println(between.getYears() + "y " + 
        between.getMonths() + "m " + 
        between.getDays() + "d"); 

रिटर्न

1997-02-28 
0y 11m 30d 
तो

LocalDate date = LocalDate.of(1996, 3, 29); 
LocalDate plusYear = date.plus(365, ChronoUnit.DAYS); 
System.out.println(plusYear); 
Period between = Period.between(date, plusYear); 
System.out.println(between.getYears() + "y " + 
        between.getMonths() + "m " + 
        between.getDays() + "d"); 

रिटर्न

1997-03-29 
1y 0m 0d 

और अंत में:

LocalDate date = LocalDate.of(1996, 2, 29); 
LocalDate plusYear = date.plus(366, ChronoUnit.DAYS); 
System.out.println(plusYear); 
Period between = Period.between(date, plusYear); 
System.out.println(between.getYears() + "y " + 
        between.getMonths() + "m " + 
        between.getDays() + "d"); 

रिटर्न:

1997-03-01 
1y 0m 1d 

कृपया ध्यान दें कि 366 के बजाय दिनों से तारीख आगे बढ़ की अवधि में वृद्धि हुई 11 महीने और 30 दिन से 1 साल और 1 दिन (2 दिन की वृद्धि!)।

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