2017-07-11 7 views
6

मैं फ़िल्टर/क्वेरी के लिए सेंटीनेल मानों के रूप में उपयोग किए जाने के लिए, ZonedDateTime और Instant.toEpochMilli() के बीच कनवर्ट कर सकते हैं जो MIN/MAX समय मानों का उपयोग करना चाहते हैं।क्या MIN/MAX मान ZonedDateTime और Instant.toEpochMilli दोनों के साथ काम करेंगे?

मैंने कोशिश की:

OffsetDateTime.MIN.toInstant().toEpochMilli(); 
OffsetDateTime.MAX.toInstant().toEpochMilli(); 

लेकिन मैं इस अपवाद प्राप्त करें:

java.lang.ArithmeticException: long overflow 

    at java.lang.Math.multiplyExact(Math.java:892) 
    at java.time.Instant.toEpochMilli(Instant.java:1237) 

और फिर मैं इस कोशिश की:

ZonedDateTime.ofInstant(Instant.MIN, ZoneId.systemDefault()); 
ZonedDateTime.ofInstant(Instant.MAX, ZoneId.systemDefault()); 

लेकिन फिर मैं इस अपवाद प्राप्त करें:

java.time.DateTimeException: Invalid value for Year (valid values -999999999 - 999999999): -1000000001 

    at java.time.temporal.ValueRange.checkValidIntValue(ValueRange.java:330) 
    at java.time.temporal.ChronoField.checkValidIntValue(ChronoField.java:722) 
    at java.time.LocalDate.ofEpochDay(LocalDate.java:341) 
    at java.time.LocalDateTime.ofEpochSecond(LocalDateTime.java:422) 
    at java.time.ZonedDateTime.create(ZonedDateTime.java:456) 
    at java.time.ZonedDateTime.ofInstant(ZonedDateTime.java:409) 

मैं भी 'Z' ZoneId की कोशिश की:

ZonedDateTime.ofInstant(Instant.MIN, ZoneId.of("Z")) 

लेकिन यह है कि पिछले एक के रूप में ही अपवाद देता है।

अंत में मैं निम्नलिखित की कोशिश की, और यह काम करने लगता है:

ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("Z")); 
ZonedDateTime.ofInstant(Instant.EPOCH.plusMillis(Long.MAX_VALUE), ZoneId.of("Z")); 

कि सबसे अच्छा समाधान है?

उत्तर

6

Instant.EPOCH1970-01-01T00:00Z के बराबर है, इसलिए मुझे यकीन नहीं है कि यह न्यूनतम मूल्य के लिए एक अच्छा उम्मीदवार है (यह आपकी आवश्यकताओं पर निर्भर करता है, बेशक - यदि आपकी सभी तिथियां 1 9 70 के बाद हैं, तो यह ठीक रहेगी)।

Instant.MIN और Instant.MAX परिवर्तित ZonedDateTime को हर समय क्योंकि ऑफसेट पर निर्भर करता है, खेतों मूल्यों के लिए सीमाओं से परे (आपके मामले में साल के साथ हुआ, जैसे) सेट किया जा सकता काम नहीं करता।

आप दूर दूर दिनांकों कि ZonedDateTime और Instant में बदला जा सकता चाहते हैं, आप में निर्मित न्यूनतम/अधिकतम स्थिरांक उपयोग करने के लिए है, क्योंकि वे बहुत दूर दिनांक (वर्षों से -१००००००००० तरह 1000000000 करने के लिए) का उपयोग की जरूरत नहीं है , और समकक्ष epoch milli ऐसी तारीखों के लिए मान long मान की सीमा से अधिक (या कम) हैं।

आप toEpochMilli() उपयोग करने की आवश्यकता है और यह एक long रिटर्न के रूप में, आप एक long मूल्य की सीमा के बीच रहना चाहिए:

Instant minInstant = Instant.ofEpochMilli(Long.MIN_VALUE); 
Instant maxInstant = Instant.ofEpochMilli(Long.MAX_VALUE); 
ZonedDateTime minZonedDateTime = minInstant.atZone(ZoneOffset.UTC); 
ZonedDateTime maxZonedDateTime = maxInstant.atZone(ZoneOffset.UTC); 

संबंधित मूल्यों हैं:

minInstant = -292275055- 05-16T16: 47: 04.192Z
maxInstant = + 2 9 2278994-08-17T07: 12: 55.807Z
minZonedDateTime = -292275055-05-16T16: 47: 04.192Z
maxZonedDateTime = + 2 9 2278994-08-17T07: 12: 55।807Z

और युग मिली लिए संबंधित मूल्यों:

System.out.println("minInstant millis=" + minInstant.toEpochMilli()); 
System.out.println("maxInstant millis=" + maxInstant.toEpochMilli()); 

minInstant मिली सेकंड = -9223372036854775808
maxInstant मिली सेकंड = 9223372036854775807

मैं कुछ विशेष समय क्षेत्र के बजाय ZoneOffset.UTC इस्तेमाल किया, क्योंकि उन तिथियों को अतीत/भविष्य में अब तक बहुत दूर है, कि कुछ घंटों का ऑफसेट बहुत अंतर नहीं करेगा। और वे सभी एक ही मिलिस तत्काल के बराबर होंगे।

आप से OffsetDateTime को atOffset विधि (जैसे minInstant.atOffset(ZoneOffset.UTC)) का उपयोग करके भी परिवर्तित कर सकते हैं।


नोट्स:

    बजाय
  • ZoneId.of("Z"), आप लगातार ZoneOffset.UTC उपयोग कर सकते हैं। दरअसल, यदि आप ZoneId.of("Z").equals(ZoneOffset.UTC) चेक करते हैं, तो परिणाम true है।
    यहां तक ​​कि ZoneId.of("Z") == ZoneOffset.UTC भी true है, इसलिए दोनों वास्तव में एक ही चीज़ हैं।
  • आपकी क्वेरी के मूल्यों के आधार पर, आपको ऐसी चरम तिथियों का उपयोग करने की आवश्यकता नहीं है। उदाहरण के लिए, आप न्यूनतम से वर्ष 1 9 00 और अधिकतम 2 9 00 सेट कर सकते हैं। यह सब आपके डेटासेट पर निर्भर करता है। लेकिन ऊपर दिए गए दृष्टिकोण का उपयोग ठीक रहेगा, यदि आपका डेटाबेस साल के लिए ऐसे बड़े मूल्यों को संभाल सकता है।
+1

यह भी ध्यान देने योग्य है कि आपकी तिथियां कितनी दूर हैं। सभी मामलों का मानना ​​है कि इसका मतलब 1 9 70 से पहले या युग के ओवरफ्लो के बाद भी हो सकता था (मेरे पास 100+ साल की तारीख के साथ एक मामला था, आप इसके लिए एमएस युग का उपयोग नहीं कर सकते हैं) – Rogue

+1

धन्यवाद @ ह्यूगो। सरल और शानदार। Long.MIN_VALUE/MAX_VALUE का उपयोग करने के लिए पूरी तरह से समझ में आता है। – jacob

+0

आपका स्वागत है, मदद करने में खुश! दरअसल, लांग मिनट और अधिकतम मूल्यों का उपयोग करके आपको एक अच्छी रेंज मिलती है (200 मिलियन से अधिक वर्षों, ज्यादातर मामलों के लिए पर्याप्त, मुझे लगता है)। –

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