2015-09-29 7 views
9

Ich denke an die Verwendung der neuen Java 8 Date Time API. Ich habe ein bisschen gegoogelt und fand jodaTime als gute Wahl für Java, aber immer noch interessiert, um zu sehen, wie diese neue API funktioniert.Behandelt die neue Java Date Time API von Java 8 die Sommerzeit?

Ich speichere alle Zeit in UTC-Werten in meinem Datenspeicher und wandle sie in einen lokalen Zeitzonen-spezifischen Wert basierend auf der Zeitzone des Benutzers um. Ich kann viele Artikel finden, die zeigen, wie man die neue Java Date Time API benutzt. Ich bin mir jedoch nicht sicher, ob die API Änderungen an der Sommerzeit vornehmen wird. Oder haben wir einen besseren Umgang mit Date?

Ich lerne gerade die neue Date API, dachte also über Ihre Gedanken über die Handhabung der DateTime und die Anzeige auf der Basis von Users TimeZone.

+3

Kurz gesagt: ja, DST ist erledigt. Java 8 Datum-Uhrzeit-API wurde basierend auf Joda Zeit erstellt. –

+1

@Raja Ich korrigiere deine Bedingungen, um Verwirrung zu vermeiden ... "Lokal" in Datum-Zeit-Arbeit bedeutet "für jeden Ort", wie in "Weihnachten beginnt um Mitternacht 25. Dezember 2015". Solch ein lokales Datum-Uhrzeit hat keine Zeitzone. In der Tat hat es keine wirkliche Bedeutung, bis Sie es in eine bestimmte Zeitzone anpassen. Mitternacht am 25. kommt früher in Paris als in Montréal. In herkömmlichen Geschäftsanwendungen verwenden wir daher selten "lokal". Sie nehmen Ihre gespeicherten Datum-Uhrzeit-Werte aus Ihrer Datenbank, arbeiten mit ihnen in Ihrer Geschäftslogik im Allgemeinen in UTC und passen sie an eine "ZonedDateTime" nur für die Präsentation an einen Benutzer an. –

Antwort

15

Es hängt davon ab, welche Klasse y ou verwenden:

  • Instant ist ein momentaner Punkt auf der globalen Zeitlinie (UTC) und ist unabhängig von Zeitzonen.
  • LocalDate und LocalDateTime haben kein Konzept der Zeitzone, aber Anruf now() wird Ihnen natürlich Ihre korrekte Zeit geben.
  • OffsetDateTime hat eine Zeitzone, unterstützt jedoch keine Sommerzeit.
  • ZonedDateTime hat volle Zeitzonenunterstützung.

zwischen ihnen Konvertierung erfordert in der Regel eine Zeitzone, damit Ihre Frage zu beantworten:

        Ja, Java 8 Datum/Zeit Pflege von DST nehmen, wenn Sie verwenden es richtig.

+0

danke für die Erwähnung, dass 'OffsetDateTime' DST nicht unterstützt, das ist genau das, was ich brauchte, danke! –

3

Ja, die Java API berücksichtigt DST-Änderungen.

Dieses Tutorial erklärt ganz gut, wie Datumsangaben zwischen Zeitzonen konvertieren und wie man die richtige Klasse zu wählen, um ein Datum zu repräsentieren: https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

Sie auch in dieser Klasse suchen können, die die Regeln für jede Zone darstellt: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html

insbesondere diese Methode kann Ihnen sagen, ob ein bestimmtes Moment in die Sommerzeit ist: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time.Instant-

+0

Vielen Dank für die Erinnerung an den Wert von Orcale Docs :) Diese Links sind hilfreicher für mich. – Raja

14

The Answer von Andreas ist genau richtig.

Beispielcode

Lass es uns mit etwas Code testen. DST in the United States & Kanada läuft in diesem Jahr um 02:00 Uhr am 1. November 2015

der auf die Timeline mit 01.00 in „local“ Datum-Zeit, also nicht gebunden Lassen Sie beginnen und die Frage der Zeitzonen zu ignorieren. Fügen Sie eine Stunde hinzu und wir bekommen 2 Uhr. Macht Sinn.

LocalDateTime localDateTime = LocalDateTime.of(2015 , Month.NOVEMBER , 1 , 1 , 0); // 1 AM anywhere. Not tied the timeline nor to any time zone. 
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours(1); // 2 AM anywhere, in no particular time zone, ignoring DST. 

Als nächstes werden wir spezifisch, mit einer bestimmten Zeitzone.Wir nehmen das 1 Uhr morgens und legen es in die Zeitzone von (Westküste der Vereinigten Staaten).

ZoneId zoneId_LosAngeles = ZoneId.of("America/Los_Angeles"); 
ZonedDateTime before = localDateTime.atZone(zoneId_LosAngeles); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line. 

Jetzt eine Stunde hinzufügen, und sehen, was wir bekommen. Wenn DST ignoriert wird, erhalten wir 2 Uhr morgens. Wenn DST respektiert wird, erhalten wir 1 AM ... wenn 2 AM erreicht wird, springt die wall-clock time zurück zu 1 AM, aber mit einem neuen Offset-von-UTC. Dies ist umgangssprachlich bekannt als "fall back" im Herbst (Herbst).

ZonedDateTime after = before.plusHours(1); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015. 

Dump zur Konsole.

System.out.println("localDateTime : " + localDateTime); 
System.out.println("localDateTimeOneHourLater : " + localDateTimeOneHourLater); 
System.out.println("before : " + before); 
System.out.println("after : " + after); 

Wenn ausgeführt, erhalten wir diese Ausgabe. Ohne Zeitzone, 1 Uhr morgens + 1 Stunde = 2 Uhr morgens. Denken Sie daran, dass dies "lokale" Datums-/Uhrzeitwerte sind, nicht UTC. Sie repräsentieren nur die vage Idee einer Datum-Zeit, nicht einen tatsächlichen Moment auf der Timeline.

localDateTime : 2015-11-01T01:00 
localDateTimeOneHourLater : 2015-11-01T02:00 

Aber mit den am Tag der Sommerzeit verfallenen Zeitzonen erhalten wir andere Ergebnisse. Beachten Sie, wie die Uhrzeit 01:00 bleibt, aber die offset-from-UTC wechselt von -07:00 zu -08:00.

before : 2015-11-01T01:00-07:00[America/Los_Angeles] 
after : 2015-11-01T01:00-08:00[America/Los_Angeles] 

Vielleicht wäre dies klarer und einfacher zu überprüfen, ob wir in UTC anpassen. Dies können wir einfach durch Zugriff auf die Objekte before und after als Objekte Instant erreichen. Die System.out.println ruft dann implizit die Methode toString auf.

System.out.println("before.toInstant : " + before.toInstant()); 
System.out.println("after.toInstant : " + after.toInstant()); 

Wenn ausgeführt.

before.toInstant : 2015-11-01T08:00:00Z 
after.toInstant : 2015-11-01T09:00:00Z