Ich habe eine Klasse mit einem Datumsfeld, das ein "Gültig ab" -Datum für ein Stück Daten darstellt. Es ist wie folgt definiert:
%Vor%Alles scheint gut zu funktionieren, genau an dem Punkt, wo ich das Datum aus der Datenbank herausziehe und es zeige. Wenn ich das Datum 18-Sep-2003 im Frontend wähle, dann speichere es, wenn ich in die Datenbank sicher genug einchecke, dass das Datum gehalten wird (Datenbank ist MySQL 5.5.9 Spaltentyp ist DATE). Wenn ich jedoch eine Liste abrufe, wird das Datum vom 17. September 2003 - einen Tag früher - angezeigt.
Wenn ich ein Datum früh oder spät im Jahr wie 26.03.2003 oder 25.12.2003 wähle, ist alles in Ordnung, also denke ich, dass dies etwas mit der Sommerzeit zu tun hat, aber wo schleicht sich der Fehler ein? Da die Datenbank das korrekte Datum zu halten scheint, muss es sein, wenn JPA wieder in eine java.util.Date konvertiert - ist java.util.Date die beste Klasse für ein Datum? Ich habe ein paar Beispiele gesehen, wo Leute Kalender benutzen, aber das scheint ziemlich schwer zu sein und ich bin mir nicht sicher, wie gut es mit einem JSF-basierten Frontend funktionieren wird.
Nach vielem Experimentieren und Suchen bin ich mir ziemlich sicher, dass ich die Ursache des Problems gefunden habe. Das Datum wird in einem java.util.Date festgehalten, das mit dem ganzen Gepäck der Zeit und einer Zeitzone kommt. Es scheint, dass JPA das Datum 18 Sep 2003 aus der Datenbank liest und dann das Datum wie folgt auffüllt: "Do 18 Sep 00:00:00 BST 2003" - Beachten Sie, dass die Zeitzone wahrscheinlich auf BST gesetzt wurde, weil dies nicht der Fall war explizit von der Datenbank festgelegt. Wie auch immer, es ist notwendig, die Ausgabe in der JSF-Seite zu formatieren, wenn Sie nur das Datum wie folgt sehen möchten:
%Vor%Dies setzt jedoch voraus, dass die Zeitzone auf dem aktuellen Stand der Maschine liegt. In meinem Fall ist die Zeitzone momentan GMT (weil es Winter ist), also wenn sie mit dem Datum "Do 18. September 00:00:00 BST 2003" präsentiert wird, wird sie in GMT umgewandelt, indem eine Stunde subtrahiert wird und das Display den 17. September 2003 anzeigt.
Sehr bedauerlich, aber alle bisherigen Antworten sind im Allgemeinen falsch. Die Antwort ist ziemlich einfach, erfordert aber, dass wir fünf Punkte trennen:
Zusammenfassung: Verwenden Sie UTC (GMT + 0) auf dem Server in der Datenbank in Ihren Java-Objekten.
DATE und TIMESTAMP unterscheiden sich nur insofern von einer Datenbankperspektive, als TIMESTAMP zusätzliche Bruchteile von Sekunden enthält. Beide verwenden GMT + 0 (impliziert). JodaTime ist ein bevorzugtes Kalenderframework, um all dies zu behandeln, aber es wird nicht die Probleme der nicht übereinstimmenden JVM mit Datenbank-Zeitzoneneinstellungen beheben.
Wenn Anwendungsentwürfe von JVM in der DB GMT nicht verwenden, aufgrund von Tageslichteinsparungen, Uhranpassungen und allen Arten von anderen regionalen Spielen, die in der Welt lokale Uhren gespielt werden ... die Zeiten von Transaktionen und alles andere wird für immer verzerrt, nicht-referentiell, inkonsistent, etc.
Eine weitere gute Antwort zu Datentypen: java.util.Date vs java .sql.Date
Beachten Sie auch, dass Java 8 Updates mit besserer Datum / Uhrzeit-Handhabung (endlich) enthält, aber dies verhindert nicht, dass die Serveruhr, auf der die JVM läuft, in einer Zeitzone und die Datenbank in einer anderen ist. An diesem Punkt findet immer eine Übersetzung statt. In jedem großen (intelligenten) Client, mit dem ich arbeite, sind die Zeitzonen der Datenbank und des JVM-Servers aus genau diesem Grund auf UTC eingestellt, auch wenn ihre Operationen in einer anderen Zeitzone stattfinden.
Ich hatte das gleiche Problem. Ich kenne den Grund nicht, aber mein Workaround war folgender:
In der Datenbank habe ich den Spaltentyp von %code% in %code% geändert.
In der Entitätsklasse habe ich die %code% Annotation geändert, aber den Datentyp %code% :
beibehalten %Vor%Sehr bedauerlich, aber alle bisherigen Antworten sind im Allgemeinen falsch. Die Antwort ist ziemlich einfach, erfordert aber, dass wir fünf Punkte trennen:
Zusammenfassung: Verwenden Sie UTC (GMT + 0) auf dem Server in der Datenbank in Ihren Java-Objekten.
DATE und TIMESTAMP unterscheiden sich nur insofern von einer Datenbankperspektive, als TIMESTAMP zusätzliche Bruchteile von Sekunden enthält. Beide verwenden GMT + 0 (impliziert). JodaTime ist ein bevorzugtes Kalenderframework, um all dies zu behandeln, aber es wird nicht die Probleme der nicht übereinstimmenden JVM mit Datenbank-Zeitzoneneinstellungen beheben.
Wenn Anwendungsentwürfe von JVM in der DB GMT nicht verwenden, aufgrund von Tageslichteinsparungen, Uhranpassungen und allen Arten von anderen regionalen Spielen, die in der Welt lokale Uhren gespielt werden ... die Zeiten von Transaktionen und alles andere wird für immer verzerrt, nicht-referentiell, inkonsistent, etc.
Eine weitere gute Antwort zu Datentypen: java.util.Date vs java .sql.Date
Beachten Sie auch, dass Java 8 Updates mit besserer Datum / Uhrzeit-Handhabung (endlich) enthält, aber dies verhindert nicht, dass die Serveruhr, auf der die JVM läuft, in einer Zeitzone und die Datenbank in einer anderen ist. An diesem Punkt findet immer eine Übersetzung statt. In jedem großen (intelligenten) Client, mit dem ich arbeite, sind die Zeitzonen der Datenbank und des JVM-Servers aus genau diesem Grund auf UTC eingestellt, auch wenn ihre Operationen in einer anderen Zeitzone stattfinden.
Hatte das gleiche Problem mit SQL Server. Das Problem war ein alter SQL-JDBC-Treiber. Hatte sqljdbc4.jar vom April 2010, das mit SQL 2000 kompatibel war und das Problem hatte, dass Daten ein oder zwei Tage zurückgingen. Dann aktualisiert auf den neuesten Treiber oder sogar auf einen von 2012 und das Problem ging weg.
Ich hatte das gleiche Problem, aber ich benutzte JSF 2 als Frontend. Wenn Sie JSF-Komponenten verwenden, sehen Sie sich diese andere Stackoverflow-Diskussion an und sehen Sie, dass JSF 2 nicht nach den erwarteten TimeZone-Regeln spielt. Die Designer haben es implementiert, um immer GMT zu verwenden. In meiner Situation hat dies dazu geführt, dass meine Daten in der Datenbank um 5 oder 6 Stunden deaktiviert waren, aber korrekt angezeigt wurden.
Ich habe eine Klasse mit einem Datumsfeld, das ein "Gültig ab" -Datum für ein Stück Daten darstellt. Es ist wie folgt definiert:
%Vor%Alles scheint gut zu funktionieren, genau an dem Punkt, wo ich das Datum aus der Datenbank herausziehe und es zeige. Wenn ich das Datum 18-Sep-2003 im Frontend wähle, dann speichere es, wenn ich in die Datenbank sicher genug einchecke, dass das Datum gehalten wird (Datenbank ist MySQL 5.5.9 Spaltentyp ist DATE). Wenn ich jedoch eine Liste abrufe, wird das Datum vom 17. September 2003 - einen Tag früher - angezeigt.
Wenn ich ein Datum früh oder spät im Jahr wie 26.03.2003 oder 25.12.2003 wähle, ist alles in Ordnung, also denke ich, dass dies etwas mit der Sommerzeit zu tun hat, aber wo schleicht sich der Fehler ein? Da die Datenbank das korrekte Datum zu halten scheint, muss es sein, wenn JPA wieder in eine java.util.Date konvertiert - ist java.util.Date die beste Klasse für ein Datum? Ich habe ein paar Beispiele gesehen, wo Leute Kalender benutzen, aber das scheint ziemlich schwer zu sein und ich bin mir nicht sicher, wie gut es mit einem JSF-basierten Frontend funktionieren wird.
Nach vielem Experimentieren und Suchen bin ich mir ziemlich sicher, dass ich die Ursache des Problems gefunden habe. Das Datum wird in einem java.util.Date festgehalten, das mit dem ganzen Gepäck der Zeit und einer Zeitzone kommt. Es scheint, dass JPA das Datum 18 Sep 2003 aus der Datenbank liest und dann das Datum wie folgt auffüllt: "Do 18 Sep 00:00:00 BST 2003" - Beachten Sie, dass die Zeitzone wahrscheinlich auf BST gesetzt wurde, weil dies nicht der Fall war explizit von der Datenbank festgelegt. Wie auch immer, es ist notwendig, die Ausgabe in der JSF-Seite zu formatieren, wenn Sie nur das Datum wie folgt sehen möchten:
%Vor%Dies setzt jedoch voraus, dass die Zeitzone auf dem aktuellen Stand der Maschine liegt. In meinem Fall ist die Zeitzone momentan GMT (weil es Winter ist), also wenn sie mit dem Datum "Do 18. September 00:00:00 BST 2003" präsentiert wird, wird sie in GMT umgewandelt, indem eine Stunde subtrahiert wird und das Display den 17. September 2003 anzeigt.
Ich hatte das gleiche Problem. Ich kenne den Grund nicht, aber mein Workaround war folgender:
In der Datenbank habe ich den Spaltentyp von DATE
in DATETIME
geändert.
In der Entitätsklasse habe ich die @Temporal
Annotation geändert, aber den Datentyp Date
:
Ich hatte das gleiche Problem, aber ich benutzte JSF 2 als Frontend. Wenn Sie JSF-Komponenten verwenden, sehen Sie sich diese andere Stackoverflow-Diskussion an und sehen Sie, dass JSF 2 nicht nach den erwarteten TimeZone-Regeln spielt. Die Designer haben es implementiert, um immer GMT zu verwenden. In meiner Situation hat dies dazu geführt, dass meine Daten in der Datenbank um 5 oder 6 Stunden deaktiviert waren, aber korrekt angezeigt wurden.
Hatte das gleiche Problem mit SQL Server. Das Problem war ein alter SQL-JDBC-Treiber. Hatte sqljdbc4.jar vom April 2010, das mit SQL 2000 kompatibel war und das Problem hatte, dass Daten ein oder zwei Tage zurückgingen. Dann aktualisiert auf den neuesten Treiber oder sogar auf einen von 2012 und das Problem ging weg.