2016-07-31 5 views
6

जावा -8 से पहले मैं हमेशा एपोक के बाद से मिलीसेकंड के रूप में संबंधित तारीख/समय रखने के आदी हो गया था और केवल मानव पठनीय तिथियों/समय के साथ, यानी यूआई या लॉग फ़ाइल में, या उपयोगकर्ता द्वारा उत्पन्न किए गए पार्सिंग के साथ कभी भी सौदा करता था इनपुट।जावा 8 युग-मिलिस टाइम स्टैम्प स्वरूपित तिथि, कैसे?

मुझे लगता है कि यह जावा -8 के साथ अभी भी सुरक्षित है, और अब मैं मिलीसेकंड टाइम स्टैंप से स्वरूपित दिनांक प्राप्त करने का सबसे संक्षिप्त तरीका ढूंढ रहा हूं। मैं Instant.getLong(...) जो मैं आधा समझ में Unsupported field: YearOfEra साथ

df = Dateformatter.ofPattern("...pattern..."); 
df.format(Instant.ofEpochMilli(timestamp)) 

की कोशिश की लेकिन यह बम बाहर। अब Instant के बजाय क्या उपयोग करना है?

LocalDateTime.ofEpoch(Instant, ZoneId) गलत लगता है, क्योंकि मुझे स्थानीय समय की परवाह नहीं है। मैं फॉर्मेटर को लागू करते समय स्थानीय समय क्षेत्र देखना चाहता हूं। आंतरिक रूप से यह केवल Instant होना चाहिए।

वही ZonedDateTime.ofInstant(Instant, ZoneId) के लिए जाता है, मैंने प्रारूपण करते समय केवल ZoneId लागू करने के लिए सोचा था। लेकिन मुझे लगता है कि DateTimeFormatter अब समय क्षेत्र के साथ सौदा नहीं करता है, ऐसा लगता है, इसलिए मुझे लगता है कि मुझे उपरोक्त में से किसी एक का उपयोग करने की आवश्यकता है।

कौन सा पसंदीदा है और क्यों? या क्या मुझे समय क्षेत्र के साथ दिनांक/समय के रूप में एक युग-मिलिस टाइम स्टैम्प को प्रारूपित करने के लिए एक और तरीका उपयोग करना चाहिए?

उत्तर

8

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

इस प्रकार, तत्काल प्रारूपित करने के लिए, आपको समय-क्षेत्र जोड़ना होगा। यह सीधे फ़ॉर्मेटर withZone(ZoneId) उपयोग करने के लिए जोड़ा जा सकता है - वहाँ मैन्युअल ZonedDateTime में बदलने की कोई जरूरत नहीं है *:

zone = ZoneId.systemDefault(); 
df = DateTimeformatter.ofPattern("...pattern...").withZone(zone); 
df.format(Instant.ofEpochMilli(timestamp)) 

* खेद जल्दी जावा 8 संस्करणों में, DateTimeformatter.withZone(ZoneId) विधि काम नहीं किया है, लेकिन इस अब किया गया है निश्चित, इसलिए यदि ऊपर दिया गया कोड काम नहीं करता है, तो नवीनतम जावा 8 पैच रिलीज में अपग्रेड करें।

संपादित करें: बस उस Instant को जोड़ने के लिए सही वर्ग है जब आप बिना किसी अन्य संदर्भ के तुरंत समय स्टोर करना चाहते हैं।

1

मैं मानता हूं कि यह कुछ उलझन में है, खासकर जब इसके पूर्ववर्ती जोडा डेटटाइम की तुलना में।

सबसे भ्रमित बात यह है कि स्थानीयडेटाइम के लिए प्रलेखन कहता है कि यह "समय-क्षेत्र के बिना दिनांक-समय" है, और फिर भी LocalDateTime.ofInstant विधि पैरामीटर के रूप में एक त्वरित और टाइमज़ोन दोनों लेता है।

यह कहा गया है कि, मुझे लगता है कि आप यूटीसी टाइमज़ोन का उपयोग करके तत्काल और LocalDateTime.ofInstant का उपयोग करके जो चाहते हैं उसे प्राप्त कर सकते हैं।

public LocalDateTime millisToDateTime(long millis) { 
    return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.of("Z"); 
} 
7

त्रुटि जब आपके पास एक Instant स्वरूपण एक फ़ॉर्मेटर साथ एक साल या अन्य क्षेत्रों की उम्मीद है निर्मित उपयोग करते हुए; एक Instant यह नहीं जानता कि कौन सा वर्ष या महीना या दिन है, यह केवल जानता है कि युग के बाद से मिलीसेकंड कितने गुजर चुके हैं। उसी पल के लिए, यह पृथ्वी के 2 अलग-अलग स्थानों पर 2 अलग-अलग दिन हो सकता है।

तो यदि आप दिन प्रिंट करना चाहते हैं तो आपको समय क्षेत्र जानकारी जोड़ने की आवश्यकता है। Instant के साथ, ZonedDateTime बनाने के लिए ZoneId के साथ इसे गठबंधन करने के लिए आप atZone(zone) पर कॉल कर सकते हैं। यह एक पल की तरह बहुत अधिक है, केवल यह कि समय क्षेत्र की जानकारी है। यदि आप सिस्टम समय क्षेत्र (चल रहे वीएम में से एक) का उपयोग करना चाहते हैं, तो आप इसे ZoneId.systemDefault() के साथ प्राप्त कर सकते हैं।

इसे प्रिंट करने के लिए, आप दो अंतर्निर्मित फॉर्मेटर ISO_OFFSET_DATE_TIME या ISO_ZONED_DATE_TIME का उपयोग कर सकते हैं। दोनों के बीच का अंतर यह है कि ज़ोन डेट डेट फॉर्मेटर आउटपुट में जोन आईडी जोड़ देगा।

Instant instant = Instant.now(); 
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; 
System.out.println(formatter.format(instant.atZone(ZoneId.systemDefault()))); 
System.out.println(formatter.format(instant.atZone(ZoneId.of("America/Los_Angeles")))); 

जब मेरे मशीन है, जो "Europe/Paris" की एक प्रणाली समय क्षेत्र है पर चलाने के लिए, आप प्राप्त करेंगे:

2016-07-31T18:58:54.108+02:00 
2016-07-31T09:58:54.108-07:00 

अगर उन एक आप के अनुरूप नहीं हैं आप निश्चित रूप से अपने खुद के फ़ॉर्मेटर निर्माण कर सकते हैं, ofPattern या बिल्डर DateTimeFormatterBuilder का उपयोग कर।

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