ich Hibernate bin mit (4.2) als meine Persistenz-Provider, und ich habe eine JPA-Entität, die ein Datumsfeld enthält:Unerwünschte automatische Zeitzonenkonvertierung unter Ruhe/JPA und JDK Datum
@Entity
@Table(name = "MY_TABLE")
public class MyTable implements Serializable {
. . .
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "START_DATE")
private Date startDate;
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
. . .
}
Die Spalte mit den entsprechenden START_DATE ist definiert als START_DATE TIMESTAMP
(keine Zeitzone).
Ich bin mit Joda-Time (2.3) intern zu meiner Anmeldung des Tag zu beschäftigen (immer in UTC) und vor nur um die Entity persistierenden, verwende ich die toDate()
Methode der DateTime
Klasse Joda einen JDK zu bekommen Date
Objekt, um die Zuordnung zu gehorchen:
public void myMethod(DateTime startDateUTC) {
. . .
MyTable table = /* obtain somehow */
table.setStartDate(startDateUTC.toDate());
. . .
}
Wenn ich mich in der DB auf dem Wert, der gespeichert wird, merke ich, dass irgendwo (JDK Hibernate?) die Standard-Zeitzone des JVM den Datumswert konvertiert unter Verwendung von wo der Code läuft. In meinem Fall ist das "Amerika/Chicago".
Das Problem manifestiert sich wirklich in der Nähe von Sommerzeit (DST). Zum Beispiel intern, wenn die Zeit ist
2014-03-09T02:55:00Z
es gespeichert wird als
09-Mar-14 03:55:00
Was möchte ich, ist es als
09-Mar-14 02:55:00
jedoch in CDT gespeichert werden, 02.55 Uhr am 9. März existiert nicht ("Spring forward"). Irgendwas (JDK? Hibernate?) Rollt das Datum weiter.
Ich möchte für den Augenblick, der in der DB gespeichert wird, in UTC sein. Schließlich habe ich es intern mit meiner Anwendung zu tun, aber sobald ich es aushändige, wird es in meine Standardzeitzone umgewandelt.
Hinweis: Ich kann die Standard-Zeitzone einstellen
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
weil die JVM verwenden, auf dem ich laufen über mehrere Anwendungen gemeinsam genutzt wird.
Wie speichere ich das Datum in UTC, ohne die JVM-Standardzeitzone auf UTC zu setzen?
Meine Schätzung ist, dass wenn Sie das Datum in der Datenbank betrachten, das Tool, das Sie verwenden, die binäre numerische Darstellung des Datums, das die Datenbank intern verwendet, in etwas, das Sie verstehen können, umwandelt: ein Datum und eine Uhrzeit formatiert mit Ihrer Zeitzone. Genau wie wenn Sie new Date() machen. ToString(): Das timezone-agnostic Date-Objekt wird mit der Standardzeitzone zu einer Zeichenkette formatiert. –