Başkaları tarafından açıklandığı gibi, orada bir süreksizlik var. Orada iki olası zaman dilimi uzaklıklar içindir 1927-12-31 23:54:08
de Asia/Shanghai
, ama sadece bir için ofset 1927-12-31 23:54:07
. Yani, hangi ofseti kullanıldığına bağlı olarak, ya bir saniye fark ya da 5 dakika ve 53 saniye fark vardır.
Ofsetlerin bu hafif kayması, alışkın olduğumuz olağan bir saatlik yaz saati (yaz saati) yerine, sorunu biraz gizliyor.
Saat dilimi veritabanının 2013a güncellemesinin bu süreksizliği birkaç saniye önce taşıdığını, ancak etkinin hala gözlemlenebilir olacağını unutmayın.
java.time
Java 8'deki yeni paket bunu daha açık bir şekilde görmenizi sağlar ve bunu ele almak için araçlar sağlar. Verilen:
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());
O durationAtEarlierOffset
zaman bir saniye, durationAtLaterOffset
beş dakika 53 saniye olacak.
Ayrıca, bu iki ofset aynıdır:
// Both have offsets +08:05:52
ZoneOffset zo3Earlier = zdt3.withEarlierOffsetAtOverlap().getOffset();
ZoneOffset zo3Later = zdt3.withLaterOffsetAtOverlap().getOffset();
Ancak bu ikisi farklı:
// +08:05:52
ZoneOffset zo4Earlier = zdt4.withEarlierOffsetAtOverlap().getOffset();
// +08:00
ZoneOffset zo4Later = zdt4.withLaterOffsetAtOverlap().getOffset();
Bununla 1927-12-31 23:59:59
birlikte aynı sorunu görebilirsiniz 1928-01-01 00:00:00
, ancak bu durumda, daha uzun sapma üreten erken ofsettir ve iki olası ofsete sahip olan önceki tarihtir.
Buna yaklaşmanın bir başka yolu da bir geçiş olup olmadığını kontrol etmektir. Bunu şu şekilde yapabiliriz:
// Null
ZoneOffsetTransition zot3 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
// An overlap transition
ZoneOffsetTransition zot4 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
Kullanarak - Birden fazla geçerli olduğunu tarih / saat veya tarih / saat o bölge kimliği için geçerli olmayan bir boşluk için ofset olduğu yerde geçiş bir örtüşme olup olmadığını kontrol edebilirsiniz isOverlap()
ve isGap()
ilgili yöntemler zot4
.
Umarım bu, Java 8 yaygın olarak kullanılabilir hale geldiğinde veya JSR 310 backport'u benimseyen Java 7 kullananlara bu tür bir sorunu çözme konusunda yardımcı olur.