जैसा कि अन्य लोगों द्वारा समझाया गया है, वहाँ एक समय की कमी है। वहाँ के लिए दो संभावित समय क्षेत्र ऑफसेट हैं 1927-12-31 23:54:08
पर Asia/Shanghai
, लेकिन केवल एक के लिए ऑफसेट 1927-12-31 23:54:07
। इसलिए, जिस पर ऑफसेट का उपयोग किया जाता है, उसके आधार पर या तो एक सेकंड का अंतर या 5 मिनट और 53 सेकंड का अंतर होता है।
आम तौर पर एक घंटे की डेलाइट सेविंग (गर्मियों के समय) के बजाय ऑफसेट्स की यह थोड़ी सी शिफ्ट, समस्या को थोड़ा प्रभावित करती है।
ध्यान दें कि टाइमज़ोन डेटाबेस के 2013a अपडेट ने कुछ सेकंड पहले इस छूट को स्थानांतरित कर दिया था, लेकिन प्रभाव अभी भी देखने योग्य होगा।
java.time
जावा 8 पर नया पैकेज इसे अधिक स्पष्ट रूप से देखने देता है, और इसे संभालने के लिए उपकरण प्रदान करता है। दिया हुआ:
DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.append(DateTimeFormatter.ISO_LOCAL_DATE);
dtfb.appendLiteral(' ');
dtfb.append(DateTimeFormatter.ISO_LOCAL_TIME);
DateTimeFormatter dtf = dtfb.toFormatter();
ZoneId shanghai = ZoneId.of("Asia/Shanghai");
String str3 = "1927-12-31 23:54:07";
String str4 = "1927-12-31 23:54:08";
ZonedDateTime zdt3 = LocalDateTime.parse(str3, dtf).atZone(shanghai);
ZonedDateTime zdt4 = LocalDateTime.parse(str4, dtf).atZone(shanghai);
Duration durationAtEarlierOffset = Duration.between(zdt3.withEarlierOffsetAtOverlap(), zdt4.withEarlierOffsetAtOverlap());
Duration durationAtLaterOffset = Duration.between(zdt3.withLaterOffsetAtOverlap(), zdt4.withLaterOffsetAtOverlap());
फिर durationAtEarlierOffset
एक सेकंड durationAtLaterOffset
होगा , जबकि पांच मिनट और 53 सेकंड का होगा।
इसके अलावा, ये दो ऑफ़सेट समान हैं:
// Both have offsets +08:05:52
ZoneOffset zo3Earlier = zdt3.withEarlierOffsetAtOverlap().getOffset();
ZoneOffset zo3Later = zdt3.withLaterOffsetAtOverlap().getOffset();
लेकिन ये दोनों अलग हैं:
// +08:05:52
ZoneOffset zo4Earlier = zdt4.withEarlierOffsetAtOverlap().getOffset();
// +08:00
ZoneOffset zo4Later = zdt4.withLaterOffsetAtOverlap().getOffset();
आप देख सकते हैं एक ही समस्या की तुलना 1927-12-31 23:59:59
के साथ 1928-01-01 00:00:00
, हालांकि, इस मामले में, यह पहले ऑफसेट कि लंबे समय तक विचलन पैदा करता है, और यह पहले की तारीख दो संभावित ऑफसेट किया है।
यह दृष्टिकोण करने का एक और तरीका यह जांचना है कि क्या कोई संक्रमण चल रहा है। हम इसे इस तरह कर सकते हैं:
// Null
ZoneOffsetTransition zot3 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
// An overlap transition
ZoneOffsetTransition zot4 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
आप जाँच सकते हैं कि क्या संक्रमण एक ओवरलैप है जहाँ उस दिनांक / समय के लिए एक से अधिक मान्य ऑफ़सेट हैं या उस ज़ोन आईडी के लिए - जहाँ दिनांक और समय मान्य नहीं है - isOverlap()
और isGap()
विधियों का उपयोग करके zot4
।
मुझे उम्मीद है कि जावा 8 के व्यापक रूप से उपलब्ध होने या जावा 7 का उपयोग करने वालों के लिए जेएसआर 310 बैकपोर्ट को अपनाने के बाद लोग इस तरह के मुद्दे को सुलझाने में मदद करेंगे।