2017-04-26 9 views
7

के साथ ZonedDateTime toString compatability मैं अपने ZonedDateTime ऑब्जेक्ट पर toString() पर कॉल करना सुनिश्चित करता हूं कि ऑब्जेक्ट आईएसओ -8601 प्रारूप का पालन करेगा।आईएसओ 8601

toString() विधि राज्यों के लिए प्रलेखन:

... उत्पादन आईएसओ 8601 के साथ संगत है अगर ऑफसेट और आईडी हैं ही

इसका मतलब यह है कि वहां मौजूद एक स्थिति जहां zdt.getOffset() zdt.getZone().getRules().getOffset(zdt.toInstant()) से कुछ अलग लौटाएगा?

यह समझ में नहीं आता है।

क्या कोई ऐसा उदाहरण प्रदान कर सकता है जिसमें ऑफ़सेट और आईडी समान नहीं हैं (यानी: जहां toString() आईएसओ -8601 का अनुपालन नहीं करता है) ताकि मैं दस्तावेज़ में विवरण को बेहतर ढंग से समझ सकूं।

धन्यवाद।

उत्तर

12

यह पूरा विनिर्देश है:

* Outputs this date-time as a {@code String}, such as 
* {@code 2007-12-03T10:15:30+01:00[Europe/Paris]}. 
* <p> 
* The format consists of the {@code LocalDateTime} followed by the {@code ZoneOffset}. 
* If the {@code ZoneId} is not the same as the offset, then the ID is output. 
* The output is compatible with ISO-8601 if the offset and ID are the same. 

जावाडोक विनिर्देश इस प्रकार जहां ऑफसेट, इस मामले में जहां ZonedDateTime बल्कि ZoneId नाम के एक से एक ZoneOffset साथ निर्माण किया है को संदर्भित करता है और आईडी एक ही कर रहे हैं:

System.out.println(ZonedDateTime.now(ZoneId.of("Europe/Paris"))); 
// 2017-04-26T15:13:12.006+02:00[Europe/Paris] 

System.out.println(ZonedDateTime.now(ZoneOffset.ofHours(2))); 
// 2017-04-26T15:13:12.016+02:00 

के रूप में देखा जा सकता है, दूसरे मामले में, जहां एक ZoneOffset प्रयोग किया जाता है में, toString() प्रारूप अंत में वर्ग कोष्ठक अनुभाग अस्वीकार करते हैं। उस खंड को छोड़कर, परिणाम आईएसओ -8601 संगत है।

String isoCompatible = zdt.toOffsetDateTime().toString(); 

या एक फ़ॉर्मेटर:

boolean iso8601Compatible = zdt.getZone() instanceof ZoneOffset; 

एक आईएसओ 8601 संगत उत्पादन उपयोग toOffsetDateTime() गारंटी देने के लिए।

+4

"या एक फॉर्मेटर": [DateTimeFormatter.ISO_OFFSET_DATE_TIME] (http://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_OFFSET_DATE_TIME) दिमाग में स्प्रिंग्स। –

0

आधिकारिक दस्तावेज के अनुसार:

प्राप्त एक पल के लिए ऑफसेट, सरल है के रूप में वहाँ है वास्तव में एक-एक पल के लिए मान्य ऑफसेट। इसके विपरीत, स्थानीय दिनांक-समय के लिए ऑफ़सेट प्राप्त करना सीधा नहीं है। तीन मामले हैं:

  • सामान्य, एक मान्य ऑफ़सेट के साथ। साल के विशाल बहुमत के लिए, सामान्य मामला लागू होता है, जहां स्थानीय दिनांक-समय के लिए एक वैध वैध ऑफसेट होता है।
  • गैप, शून्य वैध ऑफसेट के साथ। यह तब होता है जब घड़ियों आगे बढ़ते हैं आमतौर पर "सर्दियों" से "गर्मी" तक वसंत डेलाइट बचत परिवर्तन के कारण। एक अंतर में स्थानीय दिनांक-समय मान हैं जिनमें वैध ऑफसेट नहीं है।
  • ओवरलैप, दो वैध ऑफसेट के साथ। यह तब होता है जब घड़ियों को आमतौर पर शरद ऋतु डेलाइट बचत परिवर्तन "ग्रीष्मकालीन" से "सर्दी" में बदल दिया जाता है। एक ओवरलैप में दो वैध ऑफसेट वाले स्थानीय दिनांक-समय मान होते हैं।

तो दूसरा और तीसरा मामला ऐसी स्थितियां हैं जहां toString() ISO-8601 अनुरूप नहीं होगा।

+0

प्रश्न 'ज़ोनडेटडेट टाइम' के बारे में था, न कि 'लोकलडेट टाइम'। 'ZonedDateTime' विशिष्ट रूप से एक पल की पहचान करता है, इसलिए मुझे समस्या दिखाई नहीं दे रही है? दूसरी तरफ, आप सही हैं कि एक 'लोकलडेट टाइम' और एक समय क्षेत्र ('जोनआईडी') एक साथ हमेशा एक तत्काल पहचान नहीं करते हैं, जैसा कि आप 2 और 3 के मामले में बताते हैं। –

+0

@ OleV.V। आपने अपने दोस्त को अपने प्रश्न का उत्तर दिया है। 'toString()' उन स्थितियों के लिए आईएसओ -8601 अनुरूप नहीं होगा जहां एक अद्वितीय इंस्टेंट की पहचान नहीं की जा सकती है। – VivekRatanSinha

+3

हालांकि यह जानकारी दिलचस्प है, दुर्भाग्यवश यह प्रश्न के लिए गलत जवाब है। गैप्स और ओवरलैप्स के पास इस मामले में आईएसओ -8601 के साथ कुछ लेना देना नहीं है। – JodaStephen

1

the documentation में उदाहरण 2007-12-03T10:15:30+01:00[Europe/Paris] है। यह आईएसओ अनुपालन नहीं होता है क्योंकि आईएसओ -8601 में [Europe/Paris] भाग शामिल नहीं है। यह java.time डेवलपर्स द्वारा मानक के करीब के रूप में एक समझौता में उचित और अभी भी समय क्षेत्र की जानकारी को एक स्पष्ट तरीके से साबित करने के बीच जोड़ा गया था। ZonedDateTime.toString(), समय क्षेत्र जानकारी है कि आईएसओ शामिल नहीं है शामिल है, तो जब परिणाम है पूरी तरह से आईएसओ शिकायत:

तो असली सवाल वास्तव में विपरीत हो सकता है? क्या होता है "अगर ऑफ़सेट और आईडी समान हैं" मतलब है? यहां हमें याद रखना होगा कि ZoneOffsetZoneID का उप-वर्ग है और ZonedDateTime में ज़ोन आईडी के रूप में उपयोग किया जा सकता है। इस मामले में ऑफ़सेट और आईडी समान हैं। अन्यथा वे नहीं हैं। एक विशिष्ट उदाहरण के लिए, ZonedDateTime.now(ZoneOffset.ofHours(+2)).toString()2017-04-26T15:04:59.828+02:00 का उत्पादन कर सकता है। यह पूरी तरह से आईएसओ संगत है क्योंकि ज़ोन को केवल +02:00 के रूप में दिया गया है, जो ऑफ़सेट के समान है। ZonedDateTime.now(ZoneOffset.UTC).toString() प्रारूप 2017-04-26T13:04:59.828Z प्रारूप में कुछ देता है। चूंकि Z ऑफ़सेट के रूप में गिना जाता है, यह भी संगत है।

मुझे लगता है कि ज्यादातर मामलों में यह बहुत उपयोगी नहीं होगा। यदि आपका क्षेत्र केवल ऑफसेट है, तो आप आमतौर पर ZonedDateTime से अधिक उपयोग करना पसंद करेंगे, और यदि ऐसा है, तो निश्चित रूप से आपको परवाह नहीं है कि ZonedDateTime.toString() आईएसओ संगत है या नहीं।

0

मुझे जोडास्टेफेन की आखिरी टिप्पणी 'या एक फॉर्मेटर' से ऊपर की तरह है, क्योंकि फॉर्मेटर का उपयोग डेटा के बावजूद अधिक मजबूत है। कारण OffsetDateTime toString() दूसरी इकाई हिस्सा छोड़ जब वहाँ दूसरी इकाई और नीचे पर कोई मूल्य नहीं है, तो यह समाप्त होता है yyyy-MM-DDThh देता है: MMZ बजाय yyyy-MM-DDThh: mm: ssZ । इससे परेशानी हो सकती है अगर अन्य सिस्टम स्थिर प्रारूप की अपेक्षा करता है और इसमें कोई अनुकूलता नहीं है।

नीचे वह कोड है जिसका उपयोग मैंने उन दोनों मामलों को अनुकरण करने के लिए किया था, जिनके पास कोई समय नहीं है और यह है।

/** 
* This function is design to convert Date object from other system to ISO dateTime String 
* which will be sent to another system. and using formatter to lock up the format 
* @param date java.util.Date 
* @return 'yyyy-MM-ddTHH:mm:ssZ' format ISO dateTime string 
*/ 
public String formatIsoUtcDateTime(Date date) { 
    if(null == date) { 
     return null; 
    } 
    return ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")) 
         .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")); 
} 

// no time portion with using formatter 
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 
Date date = sdf.parse("20171010"); 
System.out.println(formatIsoUtcDateTime(date)); 

// no time portion with using OffsetDateTime toString 
System.out.println(ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC")).toOffsetDateTime().toString()); 

// just current date and probably has at least millisecond, using formatter 
System.out.println(formatIsoUtcDateTime(new Date())); 

// just current date and probably has at least millisecond, using OffsetDateTime toString 
// this will print yyyy-MM-ddTHH:mm:ss.SSSZ format 
System.out.println(ZonedDateTime.ofInstant(new Date().toInstant(), ZoneId.of("UTC")).toOffsetDateTime().toString()); 
संबंधित मुद्दे