क्यों ZoneOffset.UTC! = ZoneId.of ("UTC") है?


125

क्यों करता है

ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
        .equals(now.withZoneSameInstant(ZoneId.of("UTC"))));

प्रिंट आउट false?

मैं दोनों ZonedDateTimeउदाहरणों के बराबर होने की उम्मीद करूंगा ।

जवाबों:


180

जवाब (जोर मेरा) के javadocZoneId से आता है ...

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

  • फिक्स्ड ऑफ़सेट्स - यूटीसी / ग्रीनविच से पूरी तरह से हल की गई ऑफसेट, जो सभी स्थानीय तिथि-समय के लिए एक ही ऑफ़सेट का उपयोग करता है
  • भौगोलिक क्षेत्र - एक ऐसा क्षेत्र जहां यूटीसी / ग्रीनविच से ऑफसेट खोजने के लिए नियमों का एक विशिष्ट सेट लागू होता है

ज़ोनऑफ़सेट द्वारा अधिकांश फिक्स्ड ऑफ़सेट्स का प्रतिनिधित्व किया जाता है। किसी भी जोन पर सामान्यीकृत () कॉलिंग यह सुनिश्चित करेगी कि एक निश्चित ऑफसेट आईडी को जोनऑफसेट के रूप में दर्शाया जाएगा।

... और (जोर मेरा) के javadoc सेZoneId#of :

यह विधि एक जोनआईड या ज़ोनऑफ़सेट बनाने वाली आईडी को पार्स करती है। यदि ID 'Z' है, या '+' या '-' से शुरू होता है, तो एक ज़ोनऑफसेट लौटा दिया जाता है

तर्क आईडी के रूप में निर्दिष्ट किया गया है "UTC", इसलिए यह ZoneIdएक ऑफसेट के साथ वापस आ जाएगा , जिसे स्ट्रिंग रूप में भी प्रस्तुत किया गया है:

System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));

आउटपुट:

2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]

जैसा कि आप equalsतुलना के लिए विधि का उपयोग करते हैं , आप ऑब्जेक्ट तुल्यता की जांच करते हैं । वर्णित अंतर के कारण, मूल्यांकन का परिणाम है false

जब normalized()विधि को दस्तावेज़ में प्रस्तावित के रूप में उपयोग किया जाता है, तो उपयोग करने वाली तुलना equalsवापस आ जाएगी true, जैसा normalized()कि संबंधित वापस आ जाएगी ZoneOffset:

समय-क्षेत्र आईडी को सामान्य करता है, जहां संभव हो वहां एक ज़ोनऑफ़सेट लौटाता है।

now.withZoneSameInstant(ZoneOffset.UTC)
    .equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true

जैसा कि प्रलेखन में कहा गया है, यदि आप उपयोग करते हैं "Z"या "+0"इनपुट आईडी के रूप ofमें, ZoneOffsetसीधे लौट आएंगे और कॉल करने की कोई आवश्यकता नहीं है normalized():

now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true

यह जाँचने के लिए कि क्या वे एक ही तारीख का समय संग्रहीत करते हैं , आप isEqualइसके बजाय विधि का उपयोग कर सकते हैं :

now.withZoneSameInstant(ZoneOffset.UTC)
    .isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true

नमूना

System.out.println("equals - ZoneId.of(\"UTC\"): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
System.out.println("equals - ZoneId.of(\"UTC\").normalized(): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())));
System.out.println("equals - ZoneId.of(\"Z\"): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("Z"))));
System.out.println("equals - ZoneId.of(\"+0\"): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("+0"))));
System.out.println("isEqual - ZoneId.of(\"UTC\"): "+ nowZoneOffset
        .isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))));

आउटपुट:

equals - ZoneId.of("UTC"): false
equals - ZoneId.of("UTC").normalized(): true
equals - ZoneId.of("Z"): true
equals - ZoneId.of("+0"): true
isEqual - ZoneId.of("UTC"): true

4
डॉक्स का यह भी कहना है कि "यदि ज़ोन आईडी 'GMT', 'UTC' या 'UT' के बराबर है, तो परिणाम उसी ID के साथ एक ZoneId है और ZoneOffset.UTC के बराबर नियम है"। एक ही आईडी और नियम, लेकिन अलग व्यवहार। ZoneId.of("Z")आपको देता है ZoneOffset.UTCलेकिन ZoneId.of("UTC")आपको एक ZoneId(जो नहीं है ZoneOffset.UTC) देता है। यह एपीआई कम से कम कहने के लिए अचूक है।
एडम मिलरचिप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.