2017-03-29 4 views
1

Für die Verbesserung der Leistung von einigen Legacy-Code, überlege ich eine Ersetzung von java.text.SimpleDateFormat durch java.time.format.DateTimeFormatter.DateTimeFormatter Parsing - Zeitzone Namen und Sommerzeit Überschneidung Zeiten

Zu den ausgeführten Aufgaben gehört die Analyse von Datum/Uhrzeit-Werten, die mit java.util.Date.toString serialisiert wurden. Mit SimpleDateFormat war es möglich, sie in die ursprünglichen Zeitstempel zurückzuverwandeln (vernachlässigen Sie die Bruchteilsekunden), jedoch habe ich Probleme, wenn ich versuche, dasselbe mit DateTimeFormatter zu machen.

Bei der Formatierung mit entweder wird meine lokale Zeitzone als CET oder CEST angezeigt, je nachdem, ob die Sommerzeit für die zu formatierende Zeit gilt. Es scheint jedoch, dass zum Zeitpunkt der Analyse sowohl CET als auch CEST durch DateTimeFormatter gleich behandelt werden.

Dies verursacht ein Problem mit der Überlappung, die am Ende der Sommerzeit auftritt. Beim Formatieren wird 02:00:00 zweimal erstellt, für Zeiten im Abstand von einer Stunde, aber mit CEST und CET-Zeitzonennamen - was in Ordnung ist. Aber bei der Parsing-Zeit kann dieser Unterschied nicht zurückgewonnen werden. Hier

ein Beispiel:

long msecPerHour = 3600000L; 
long cet_dst_2016 = 1477778400000L; 
DateTimeFormatter formatter = 
    DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH); 
ZoneId timezone = ZoneId.of("Europe/Berlin"); 
for (int hours = 0; hours < 6; ++hours) { 
    long time = cet_dst_2016 + msecPerHour * hours; 
    String formatted = formatter.format(Instant.ofEpochMilli(time).atZone(timezone)); 
    long parsedTime = Instant.from(formatter.parse(formatted)).toEpochMilli(); 
    System.out.println(formatted + ", diff: " + (parsedTime - time)); 
} 

die Ergebnisse in

Sun Oct 30 00:00:00 CEST 2016, diff: 0 
Sun Oct 30 01:00:00 CEST 2016, diff: 0 
Sun Oct 30 02:00:00 CEST 2016, diff: 0 
Sun Oct 30 02:00:00 CET 2016, diff: -3600000 
Sun Oct 30 03:00:00 CET 2016, diff: 0 
Sun Oct 30 04:00:00 CET 2016, diff: 0 

Es zeigt, dass das zweite Auftreten von 02.00.00, trotz der unterschiedlichen Zeitzone Namen, wie das behandelt wurde, Erster. Das Ergebnis ist effektiv um eine Stunde abgelaufen.

Offensichtlich hat die formatierte Zeichenfolge alle Informationen verfügbar, und SimpleDateFormat Parsing tatsächlich geehrt es. Ist es möglich, mit DateTimeFormatter mit dem angegebenen Muster durch Formatierung und Parsing zu gehen?

Antwort

3

Es ist möglich, für einen konkreten Fall:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    .appendPattern("EEE MMM dd HH:mm:ss ") 
    .appendText(OFFSET_SECONDS, ImmutableMap.of(2L * 60 * 60, "CEST", 1L * 60 * 60, "CET")) 
    .appendPattern(" yyyy") 
    .toFormatter(Locale.ENGLISH); 

Dies bildet die genau zu dem erwarteten Text versetzt. Wenn dies nicht möglich ist, müssen Sie mit mehr als einer Zeitzone umgehen.

Um die Aufgabe ordnungsgemäß ausführen zu können, benötigen Sie eine JDK change.

+0

Vielen Dank, auch für die Einreichung der JDK-Ausgabe. In der Tat muss ich auch andere Zeitzonen unterstützen (z. B. PDT/PST), also bleibe ich beim Parsen mit SimpleDateFormat für Muster, die 'z'-Spezifizierer enthalten. – Gunther

+0

Vielen Dank für den sauberen Code! – Hemin