Mysql
 sql >> Datenbank >  >> RDS >> Mysql

JPA TemporalType.Date gibt falsches Datum an

Es tut mir sehr leid, aber alle bisherigen Antworten sind im Allgemeinen falsch. Die Antwort ist recht einfach, erfordert jedoch, dass wir fünf Punkte trennen:

  1. DATE =java.sql.Date, ein Wrapper um java.util.Date, der die Anzahl der Millisekunden seit der Epoche in der UTC-Zeitzone darstellt. Dies hat also Jahr/Monat/Datum/Stunden/Minuten/Sekunden in einer festen Zeitzone GMT+0 (UTC). Beachten Sie jedoch, dass java.sql.Date die Zeitkomponenten auf Null setzt!
  2. TIMESTAMP =java.sql.TimeStamp, ein Komponenten-Wrapper um Date, der Bruchteile von Sekunden hinzufügt, um den SQL-DATE-Typstandard zu unterstützen. Diese Klasse/Typ ist für diese Frage nicht relevant oder erforderlich, aber kurz gesagt, dies hat das Datum plus die Uhrzeit.
  3. Die Datenbank speichert DATE-Objekte wie definiert (unter Verwendung von UTC als Offset von Java), aber darf übersetzen Sie die Uhrzeit, wenn sie in der Datenbank für eine andere Zeitzone konfiguriert ist. Standardmäßig verwenden die meisten Datenbanken die Zeitzone des lokalen Servers, was eine sehr schlechte Idee ist. Meine Damen und Herren ... Speichern Sie DATE-Objekte IMMER in UTC. Weiterlesen...
  4. Die Uhrzeit in der JVM und die Zeitzone müssen stimmen. Da das Date-Objekt UTC verwendet, wird ein Offset für Ihre Serverzeit berechnet? Beachten Sie dies mit der dringenden Empfehlung, die Serverzeit auf GMT+0 (UTC) einzustellen.
  5. Wenn wir schließlich das DATE aus der Datenbank rendern wollen (mit JSF oder was auch immer), sollte es auf die Zeitzone GMT+0 eingestellt werden und, wenn dies auch von der Serverseite aus gemacht wird ... Ihre Daten und Zeiten werden IMMER konsistent, referenziell und alle guten Dinge sein. Alles, was übrig bleibt, ist, die Zeit zu rendern, und DAS ist, wo der Benutzeragent (zum Beispiel für eine Webanwendung) könnte verwendet werden, um die GMT+0-Zeit in die "lokale" Zeitzone des Benutzers zu übersetzen.

Zusammenfassung:Verwenden Sie UTC (GMT+0) auf dem Server, in der Datenbank, in Ihren Java-Objekten.

DATE und TIMESTAMP unterscheiden sich aus Datenbanksicht nur dadurch, dass TIMESTAMP zusätzliche Sekundenbruchteile trägt. Beide verwenden GMT+0 (impliziert). JodaTime ist ein bevorzugtes Kalender-Framework, um all dies zu bewältigen, wird jedoch nicht die Probleme von nicht übereinstimmenden JVM-zu-Datenbank-Zeitzoneneinstellungen beheben.

Wenn Anwendungsdesigns von JVM bis zur DB GMT nicht verwenden, aufgrund von Sommerzeit, Zeitumstellungen und allerlei anderen regionalen Spielen, die in den lokalen Uhren der Welt gespielt werden, werden die Zeiten von Transaktionen und alles andere für immer verzerrt sein , nicht referenziell, inkonsistent usw.

Eine weitere gute verwandte Antwort zu Datentypen:java.util .Date vs. java.sql.Date

Beachten Sie auch, dass Java 8 (endlich) Updates mit besserer Datums-/Uhrzeitbehandlung enthält, aber dies behebt nicht, dass sich die Serveruhr, auf der die JVM ausgeführt wird, in einer Zeitzone befindet und die Datenbank in einer anderen. An dieser Stelle findet immer eine Übersetzung statt. In jedem großen (intelligenten) Client, mit dem ich arbeite, sind die Zeitzonen der Datenbank und des JVM-Servers genau aus diesem Grund auf UTC eingestellt, auch wenn ihre Operationen größtenteils in einer anderen Zeitzone stattfinden.