Come spiegato da altri, c'è una discontinuità temporale lì. Esistono due possibili offset del fuso orario per 1927-12-31 23:54:08
at Asia/Shanghai
, ma solo un offset per 1927-12-31 23:54:07
. Quindi, a seconda dell'offset utilizzato, c'è una differenza di un secondo o una differenza di 5 minuti e 53 secondi.
Questo leggero spostamento delle compensazioni, invece del solito ora legale di un'ora (ora legale) a cui siamo abituati, oscura un po 'il problema.
Si noti che l'aggiornamento 2013a del database del fuso orario ha spostato questa discontinuità pochi secondi prima, ma l'effetto sarebbe comunque osservabile.
Il nuovo java.time
pacchetto su Java 8 consente di vedere questo in modo più chiaro e fornisce strumenti per gestirlo. Dato:
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());
Quindi durationAtEarlierOffset
sarà un secondo, mentre durationAtLaterOffset
saranno cinque minuti e 53 secondi.
Inoltre, questi due offset sono uguali:
// Both have offsets +08:05:52
ZoneOffset zo3Earlier = zdt3.withEarlierOffsetAtOverlap().getOffset();
ZoneOffset zo3Later = zdt3.withLaterOffsetAtOverlap().getOffset();
Ma questi due sono diversi:
// +08:05:52
ZoneOffset zo4Earlier = zdt4.withEarlierOffsetAtOverlap().getOffset();
// +08:00
ZoneOffset zo4Later = zdt4.withLaterOffsetAtOverlap().getOffset();
Si può vedere lo stesso problema a confronto 1927-12-31 23:59:59
con 1928-01-01 00:00:00
, però, in questo caso, è la prima di offset che produce la divergenza più a lungo, ed è la data in precedenza che ha due possibili compensazioni.
Un altro modo per affrontarlo è verificare se è in corso una transizione. Possiamo farlo in questo modo:
// Null
ZoneOffsetTransition zot3 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
// An overlap transition
ZoneOffsetTransition zot4 = shanghai.getRules().getTransition(ld3.toLocalDateTime);
Puoi verificare se la transizione è una sovrapposizione in cui esiste più di un offset valido per quella data / ora o un intervallo in cui quella data / ora non è valida per quell'ID zona - utilizzando i metodi isOverlap()
e .isGap()
zot4
Spero che questo aiuti le persone a gestire questo tipo di problema una volta che Java 8 sarà diventato ampiamente disponibile, o per coloro che usano Java 7 che adottano il backport JSR 310.