2017-12-05 5 views
0

Ich habe folgende 2 Eingabezeichenfolgen:Warum einige Daten als BST und einige als GMT beim Formatieren des Datums angezeigt werden?

String string1 = "2017-01-30T13:00:00+0000" 
String string2 = "2018-06-23T16:00:00+0000" 

Für Zeichenfolge1 ich als Datum folgenden bin immer wenn ich das tue:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); 
Date startDate = formatter.parse(string1); 

Ergebnis - Mon Jan 30 13:00:00 GMT 2017

Aber wenn ich das gleiche für string2 Ich bekomme in meinem Debugger folgendes:

Sat Jun 23 17:00:00 BST 2018 

Warum bekomme ich hier unterschiedliche Zeitzonen?

+1

Wahrscheinlich, wie es Ihre Standardgebietsschema verwendet und das Uk wechselt zwischen Zeitzonen in Übereinstimmung mit dem Datum. –

+0

ja gleichen Formatierer, @ d.j.brown wie kann ich das lösen, damit beide Daten immer in GMT sind? – java123999

+1

'formatter.setTimeZone (TimeZone.getTimeZone (" GMT "));' –

Antwort

2

tl; dr

OffsetDateTime.parse("2017-01-30T13:00:00+0000") 

java.time

Unter den vielen Konstruktionsfehler der störenden alten Legacy-Klassen ist, dass Sie verwenden, dass die Date::toString Methode, um Ihre JVM Zone aktuellen Standardzeit gilt, während die Erzeugung von Zeichenfolge. Während also der Wert intern tatsächlich in UTC ist, scheint es verwirrend eine andere Zeitzone zu haben. Fügen Sie dazu hinzu, dass Ihre aktuelle Standardzeitzone eine Sommerzeitumstellung zwischen Ihren beiden Daten durchläuft.

Verwenden Sie stattdessen moderne java.time-Klassen. Analysieren Sie Ihre Eingabezeichenfolgen als OffsetDateTime Objekte.

OffsetDateTime odt = OffsetDateTime.parse("2017-01-30T13:00:00+0000") ; 

Ein Fehler in Java 8 und Java 9 könnte beißen auf Parsen Ihre Offset-von-UTC einen Doppelpunkt zwischen Stunden und Minuten fehlt. Um das Problem zu umgehen, fügen Sie den Doppelpunkt hinzu.

Anruf toString einen String in der Norm ISO 8601-Format zu erzeugen. Ergebnis ist nicht verfälscht von einer beliebigen Zeitzone dynamisch angewendet, im Gegensatz zu Date.

Falls gewünscht, vergeben Sie eine ZoneId, um eine ZonedDateTime zu erhalten.

Festlegen eines proper time zone name im Format von continent/region wie America/Montreal, Africa/Casablanca oder Pacific/Auckland. Verwenden Sie niemals die Abkürzung 3-4 Buchstaben wie BST oder EST oder IST, da diese nicht echte Zeitzonen sind, nicht standardisiert und nicht einmal eindeutig (!).

ZoneId z = ZoneId.of("Europe/London") ; 
ZonedDateTime zdt = odt.atZoneSameInstant(z) ; 

Siehe complete code for both inputs run live at IdeOne.com.

String input2017 = "2017-01-30T13:00:00+0000".replace("+0000" , "+00:00") ; // Workaround Java 8 bug where omitted colon in offset-from-UTC fails to parse. Fixed in Java 9. 
OffsetDateTime odt2017 = OffsetDateTime.parse(input2017) ; 

String input2018 = "2018-06-23T16:00:00+0000".replace("+0000" , "+00:00") ; // Workaround Java 8 bug where omitted colon in offset-from-UTC fails to parse. Fixed in Java 9. 
OffsetDateTime odt2018 = OffsetDateTime.parse(input2018) ; 

ZoneId z = ZoneId.of("Europe/London") ; 
ZonedDateTime zdt2017 = odt2017.atZoneSameInstant(z) ; 
ZonedDateTime zdt2018 = odt2018.atZoneSameInstant(z) ; 

Dump zur Konsole.

System.out.println("input2017: " + input2017) ; 
System.out.println("odt2017: " + odt2017) ; 
System.out.println("zdt2017: " + zdt2017) ; 
System.out.println("") ; // Blank line. 

System.out.println("input2018: " + input2018) ; 
System.out.println("odt2018: " + odt2018) ; 
System.out.println("zdt2018: " + zdt2018) ; 

Beachten Sie, wie im Juni 2018 Europe/London Zeit wegen Daylight Saving Time (DST) eine Stunde vorgestellt springt. Im Winter ist die Londoner Zone in UTC, aber im Sommer, eine Stunde voraus von UTC.

input2017: 2017-01-30T13: 00: 00 + 00: 00

odt2017: 2017-01-30T13: 00Z

zdt2017: 2017-01-30T13 : 00Z [Europa/London]

input2018: 2018-06-23T16: 00: 00 + 00: 00

odt2018: 2018-06-23T16: 00Z

zdt2018: 2018-06-23T17: 00 + 01: 00 [Europe/London]

Suchen Sie Stack Overflow für viel mehr Informationen, da dieses Thema schon viele Male behandelt wurde.


Über java.time

Der java.time Rahmen in Java 8 gebaut und später. Diese Klassen ersetzen die problematischen alten legacy Datum-Uhrzeit-Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Das Projekt Joda-Time, jetzt in maintenance mode, rät zur Migration auf die Klassen java.time.

Weitere Informationen finden Sie unter Oracle Tutorial. Und suchen Sie nach Stack Overflow für viele Beispiele und Erklärungen. Spezifikation ist JSR 310.

Sie können java.time Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie eine JDBC driver konform mit JDBC 4.2 oder höher. Keine Notwendigkeit für Strings, keine Notwendigkeit für java.sql.* Klassen.

Wo erhalten Sie die Klassen java.time?

  • Java SE 8, Java SE 9 und später
    • Built-in.
    • Teil der Standard-Java-API mit einer gebündelten Implementierung.
    • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 und Java SE 7
    • Ein großer Teil der java.time Funktionalität zurückportiert zu Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Spätere Versionen von Android-Bundle Implementierungen der java.time Klassen.
    • Für frühere Android, das ThreeTenABP Projekt passt ThreeTen-Backport (oben erwähnt). Siehe How to use ThreeTenABP….

Das ThreeTen-Extra Projekt erstreckt java.time mit zusätzlichen Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Erweiterungen von java.time. Hier finden Sie einige nützliche Klassen wie Interval, , YearQuarter und more.

+0

@ OleV.V. Tippfehler behoben. Vielen Dank. –

Verwandte Themen