Wie von anderen erklärt, gibt es dort eine zeitliche Diskontinuität. Es gibt zwei mögliche Zeitzonenversätze für 1927-12-31 23:54:08
at Asia/Shanghai
, aber nur einen Versatz für 1927-12-31 23:54:07
. Je nachdem, welcher Offset verwendet wird, gibt es entweder einen Unterschied von einer Sekunde oder einen Unterschied von 5 Minuten und 53 Sekunden.
Diese leichte Verschiebung der Offsets anstelle der üblichen einstündigen Sommerzeit (Sommerzeit), die wir gewohnt sind, verschleiert das Problem ein wenig.
Beachten Sie, dass das 2013a-Update der Zeitzonendatenbank diese Diskontinuität einige Sekunden zuvor verschoben hat, der Effekt jedoch weiterhin sichtbar ist.
Mit dem neuen java.time
Paket unter Java 8 können Sie dies klarer sehen und Tools bereitstellen, um damit umzugehen. Gegeben:
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());
Dann durationAtEarlierOffset
ist es eine Sekunde, während durationAtLaterOffset
es fünf Minuten und 53 Sekunden sind.
Auch diese beiden Offsets sind gleich:
// Both have offsets +08:05:52
ZoneOffset zo3Earlier = zdt3.withEarlierOffsetAtOverlap().getOffset();
ZoneOffset zo3Later = zdt3.withLaterOffsetAtOverlap().getOffset();
Aber diese beiden sind unterschiedlich:
// +08:05:52
ZoneOffset zo4Earlier = zdt4.withEarlierOffsetAtOverlap().getOffset();
// +08:00
ZoneOffset zo4Later = zdt4.withLaterOffsetAtOverlap().getOffset();
Sie können das gleiche Problem zu vergleichen sehen 1927-12-31 23:59:59
mit 1928-01-01 00:00:00
, in diesem Fall aber ist es der frühere Zeitpunkt ist versetzt , dass die längere Divergenz erzeugt, und es ist das frühere Datum , die zwei mögliche Offsets hat.
Eine andere Möglichkeit, dies zu erreichen, besteht darin, zu überprüfen, ob ein Übergang stattfindet. Wir können das so machen:
// Null
ZoneOffsetTransition zot3 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
// An overlap transition
ZoneOffsetTransition zot4 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
Sie können überprüfen, ob der Übergang eine Überlappung ist, bei der es mehr als einen gültigen Versatz für dieses Datum / diese Uhrzeit gibt, oder eine Lücke, bei der dieses Datum / diese Uhrzeit für diese Zonen-ID nicht gültig ist, indem Sie die Methoden isOverlap()
und isGap()
verwenden zot4
.
Ich hoffe, dies hilft den Leuten, diese Art von Problem zu lösen, sobald Java 8 allgemein verfügbar ist, oder für diejenigen, die Java 7 verwenden und den JSR 310-Backport verwenden.