2014-06-30 7 views
31

नई JSR 310 तारीख एपीआई (java.time package) जावा 8 में उपलब्ध है और में Duration वर्ग के बाद, जावाडोक का कहना है:जावा.टाइम में मिनट या घंटे में मुझे अवधि क्यों नहीं मिल सकती है?

इस वर्ग के मॉडल एक मात्रा या समय की राशि सेकंड के मामले और नैनोसेकंड में। यह मिनट और घंटे .इसके अलावा के रूप में अन्य अवधि आधारित इकाइयों, का उपयोग कर पहुँचा जा सकता है, दिन इकाई इस्तेमाल किया जा सकता है और वास्तव में 24 घंटे के बराबर माना जाता है, इस प्रकार डेलाइट सेविंग प्रभाव की अनदेखी।

तो, क्यों निम्नलिखित कोड दुर्घटना करता है?

Duration duration = Duration.ofSeconds(3000); 
System.out.println(duration.get(ChronoUnit.MINUTES)); 

यह एक UnsupportedTemporalTypeException को जन्म देती है:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Minutes 
    at java.time.Duration.get(Duration.java:537) 

तो एक अवधि वस्तु से मिनट और घंटे को निकालने के लिए सुझाया गया तरीका क्या है? क्या हमें खुद को सेकेंड की संख्या से गणना करना है? इसे इस तरह क्यों लागू किया गया था?

+2

मिल http://stackoverflow.com/questions/20827047/formatting-a-duration-in-java-8-jsr310 (स्वीकार्य उत्तर नहीं) –

+1

FY मैं, java.time, [थ्रीटेन अतिरिक्त] (http://www.threeten.org/threeten-extra/) का विस्तार करने के लिए एक परियोजना है। लेकिन मुझे नहीं लगता कि वर्तमान में आपकी मदद करने के लिए कुछ भी है। –

+2

लगता है कि जेएसआर 310 जावा.टाइम वह सब कुछ नहीं है जिसे हमने आशा की थी। यह [जोडा-टाइम] (http://www.joda.org/joda-time/) के लिए एक पूर्ण और बेहतर प्रतिस्थापन नहीं है। जबकि जावा.टाइम की ताकत है, तो जोडा-टाइम भी करता है। जोडा-टाइम समय की अवधि (अवधि, अवधि, अंतराल) को संभालने के लिए तीन कक्षाएं प्रदान करता है, इसमें स्पैन के आईएसओ 8601 स्ट्रिंग का प्रतिनिधित्व करने के लिए अच्छा अंतर्निहित समर्थन है, और अपने स्वयं के स्वरूपण को परिभाषित करने के लिए अच्छा समर्थन है। –

उत्तर

44

"इसे इस तरह क्यों लागू किया गया था?"

अन्य उत्तरों toXxx() विधियों के साथ सौदा करते हैं जो घंटों/मिनटों की पूछताछ की अनुमति देते हैं। मैं क्यों निपटने की कोशिश करूंगा।

TemporalAmount इंटरफ़ेस और get(TemporalUnit) विधि प्रक्रिया में काफी देर से जोड़ा गया था। मैं व्यक्तिगत रूप से पूरी तरह से आश्वस्त नहीं था कि उस क्षेत्र में डिजाइन करने के लिए हमारे पास सही तरीके से पर्याप्त सबूत थे, लेकिन TemporalAmount जोड़ने के लिए थोड़ा हाथ-मोड़ था। मेरा मानना ​​है कि ऐसा करने में हमने एपीआई को थोड़ा उलझन में डाल दिया।

हिंडसाइट में, मुझे विश्वास है कि TemporalAmount में सही तरीके हैं, लेकिन मेरा मानना ​​है कि get(TemporalUnit) का एक अलग तरीका नाम होना चाहिए था। कारण यह है कि get(TemporalUnit) अनिवार्य रूप से एक ढांचा-स्तर विधि है - यह दिन-आज के उपयोग के लिए डिज़ाइन नहीं किया गया है। दुर्भाग्यवश विधि का नाम get इसका अर्थ नहीं है, जिसके परिणामस्वरूप get(ChronoUnit.MINUTES) पर Duration पर बग जैसे परिणाम हैं।

तो, जिस तरह से get(TemporalUnit) के बारे में सोचना एक निम्न स्तर के ढांचे के एक Map<TemporalUnit, Long> जहां DurationSECONDS और NANOS की कुंजी के साथ दो आकार के एक Map है के रूप में राशि को देखने की कल्पना करना है। DAYS, MONTHS और YEARS (जो सौभाग्य से त्रुटियों की संभावना उतनी ही कम है) -

एक ही है, रास्ते में, Period तीन आकार का एक Map के रूप में निम्न स्तर के चौखटे से देखा जाता है।

कुल मिलाकर, एप्लिकेशन कोड के लिए सबसे अच्छी सलाह get(TemporalUnit) विधि को अनदेखा करना है। getSeconds(), getNano(), toHours() और toMinutes() का उपयोग करें।

अंत में, एक ही रास्ता पाने के लिए "hh: mm: ss" एक Duration से करना है:

LocalTime.MIDNIGHT.plus(duration).format(DateTimeFormatter.ofPattern("HH:mm:ss")) 

नहीं सुंदर सब पर है, लेकिन यह करता है एक दिन से भी कम समय अवधि के लिए काम करते हैं। जावा 9 में

JDK-8142936 मुद्दा

न्यू to…Part तरीके अब जावा 9 में लागू, एक Duration के प्रत्येक भाग का उपयोग करने के लिए निम्न विधियों में जोड़ने।

  • toDaysPart
  • toHoursPart
  • toMinutesPart
  • toSecondsPart
  • toMillisPart
  • toNanosPart

+0

क्यों दिलचस्प अंदरूनी दृश्य के लिए धन्यवाद, और उपयोगी छोटी स्वरूपण चाल :) –

20

documentation का कहना है:

यह दो समर्थित इकाइयों, सेकंड और Nanos से प्रत्येक के लिए एक मान देता है। अन्य सभी इकाइयां एक अपवाद फेंकती हैं।

तो, सबसे अच्छा अनुमान जवाब - इस तरह से वे इसे तैयार किया गया है।

long hours = duration.toHours(); 

या minutes:

आप अन्य तरीकों के कुछ hours में इसे पाने के लिए उपयोग कर सकते हैं

long minutes = duration.toMinutes(); 
+2

दिलचस्प। मैं वास्तव में उन XXX तरीकों से नहीं देखा था। लेकिन वे बेहतर इकाइयों को ध्यान में रखे बिना, सेकंड की कुल संख्या को आवश्यक इकाई में परिवर्तित करते हैं। उदाहरण: '10000' सेकंड की अवधि के लिए, 'toMinutes()' विधि 166 वापस आ जाएगी। यदि आपको' hh: mm: ss' प्रदर्शित करने की आवश्यकता है तो इतना उपयोगी नहीं है, लेकिन अधिक पूर्ण गणना विधि के हिस्से के रूप में उपयोग किया जा सकता है । –

+0

@PierreHenry ठीक है, यह वास्तव में आपके इच्छित प्रारूप में नहीं है, लेकिन आप मानव-पठनीय मूल्य – blgt

+0

के रूप में अवधि प्राप्त करने के लिए 'duration.toString()' का उपयोग कर सकते हैं केवल घंटे घटक (दिनों के बिना) प्राप्त करने के लिए: int घंटे = (int) (अवधि।toHours()% 24L); ' – MT0

5

एक "सामान्यीकृत" रास्ते में घंटे/मिनट/सेकंड घटक प्राप्त करने के लिए , आपको उन्हें मैन्युअल रूप से गणना करने की आवश्यकता है - नीचे दिया गया कोड अनिवार्य रूप से Duration#toString विधि से कॉपी किया गया है:

Duration duration = Duration.ofSeconds(3000); 
long hours = duration.toHours(); 
int minutes = (int) ((duration.getSeconds() % (60 * 60))/60); 
int seconds = (int) (duration.getSeconds() % 60); 
System.out.println(hours + ":" + minutes + ":" + seconds); 
+0

मुझे ऐसा करने के लिए [अवधि] (http://docs.oracle.com/javase/8/docs/api/java/time/Duration.html) API नहीं मिल रहा है। तो मैं इस जवाब का पालन करता हूं। –

6

मैं bigt के उत्तर (+1) में जोड़ना चाहता हूं जो उपयोगी toHours, toMinutes और अन्य रूपांतरण विधियों को इंगित करता है। Duration specification का कहना है:

इस वर्ग के मॉडल एक मात्रा या समय की राशि सेकंड और नैनोसेकंड के संदर्भ में। [...]

अवधि की सीमा एक नंबर एक लंबे से बड़ा के भंडारण की आवश्यकता है। इसे प्राप्त करने के लिए, कक्षा लंबे समय तक प्रतिनिधित्व करने वाले सेकंड और एक इंट का प्रतिनिधित्व करती है जो नैनोसेकंड-ऑफ-सेकेंड का प्रतिनिधित्व करती है, जो हमेशा 0 और 99 9, 999, 999 के बीच होगी।

ऐसे getSeconds, getNano, और get(TemporalUnit) रूप गेटर लिए विभिन्न तरीकों का कर रहे हैं। यह देखते हुए कि एक अवधि को (सेकेंड, नैनो) जोड़ी के रूप में दर्शाया गया है, यह स्पष्ट है कि get(TemporalUnit) सेकंड और नैनो तक सीमित क्यों है। ये गेटर विधियां सीधे अवधि के उदाहरण से डेटा निकालती हैं और हानिरहित होती हैं।

इसके विपरीत, वहाँ करने के लिए तरीकों toDays, toHours, toMillis toMinutes, और toNanos कि अवधि मान पर रूपांतरण कर सहित की एक किस्म है। ये रूपांतरण हानिकारक हैं कि उनमें डेटा का छंटनी शामिल है, या यदि वे अनुरोधित प्रारूप में अवधि मान का प्रतिनिधित्व नहीं कर सकते हैं तो वे अपवाद फेंक सकते हैं।

यह स्पष्ट रूप से डिज़ाइन का हिस्सा है कि प्राप्त विधियों रूपांतरण के बिना डेटा निकालते हैं और टू-विधियां किसी प्रकार के रूपांतरण करती हैं।

0

नीचे कोड मैं इस अवधि उत्पादन मिल द्वारा:

1 दिन, 2 घंटे, 5 मिनट

कोड उदाहरण:

private String getDurationAsString(Duration duration) 
{ 
    StringBuilder durationAsStringBuilder = new StringBuilder(); 
    if (duration.toDays() > 0) 
    { 
     String postfix = duration.toDays() == 1 ? "" : "s"; 
     durationAsStringBuilder.append(duration.toDays() + " day"); 
     durationAsStringBuilder.append(postfix); 
    } 

    duration = duration.minusDays(duration.toDays()); 
    long hours = duration.toHours(); 
    if (hours > 0) 
    { 
     String prefix = Utils.isEmpty(durationAsStringBuilder.toString()) ? "" : ", "; 
     String postfix = hours == 1 ? "" : "s"; 
     durationAsStringBuilder.append(prefix); 
     durationAsStringBuilder.append(hours + " hour"); 
     durationAsStringBuilder.append(postfix); 
    } 

    duration = duration.minusHours(duration.toHours()); 
    long minutes = duration.toMinutes(); 
    if (minutes > 0) 
    { 
     String prefix = Utils.isEmpty(durationAsStringBuilder.toString()) ? "" : ", "; 
     String postfix = minutes == 1 ? "" : "s"; 
     durationAsStringBuilder.append(prefix); 
     durationAsStringBuilder.append(minutes + " minute"); 
     durationAsStringBuilder.append(postfix); 
    } 

    return durationAsStringBuilder.toString(); 
} 

स्पष्टीकरण:

अवधि इंटरफ़ेस का उपयोग कर आप आसानी से सटीक पा सकते हैं तक स्ट्रिंग डिस्प्ले जो आप चाहते हैं। आपको वर्तमान अवधि से बड़े टेम्पोरल यूनिट को कम करने की आवश्यकता है।

उदाहरण के लिए

:

  1. calculate दिनों
  2. अवधि से दिनों को कम
  3. calculate घंटे
  4. अवधि आदि से घंटे को कम ... जब तक यू अवधि = 0
संबंधित मुद्दे