Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Ist java.sql.Timestamp zeitzonenspezifisch?

Obwohl es nicht explizit für setTimestamp(int parameterIndex, Timestamp x) angegeben ist Fahrer müssen die Regeln befolgen, die durch setTimestamp(int parameterIndex, Timestamp x, Calendar cal) festgelegt wurden javadoc:

Legt den angegebenen Parameter auf den angegebenen java.sql.Timestamp fest Wert, unter Verwendung des gegebenen Calendar Objekt. Der Treiber verwendet den Calendar -Objekt, um einen SQL TIMESTAMP zu erstellen Wert, den der Treiber dann an die Datenbank sendet. Mit einem Calendar -Objekt kann der Fahrer den Zeitstempel unter Berücksichtigung einer benutzerdefinierten Zeitzone berechnen. Wenn kein Calendar -Objekt angegeben ist, verwendet der Treiber die Standardzeitzone, die der virtuellen Maschine entspricht, auf der die Anwendung ausgeführt wird.

Beim Aufruf mit setTimestamp(int parameterIndex, Timestamp x) Der JDBC-Treiber verwendet die Zeitzone der virtuellen Maschine, um das Datum und die Uhrzeit des Zeitstempels in dieser Zeitzone zu berechnen. Dieses Datum und diese Uhrzeit werden in der Datenbank gespeichert, und wenn die Datenbankspalte keine Zeitzoneninformationen speichert, gehen alle Informationen über die Zone verloren (was bedeutet, dass es Sache der Anwendung(en) ist, die die Datenbank verwenden, die zu verwenden konsistent dieselbe Zeitzone oder lassen Sie sich ein anderes Schema einfallen, um die Zeitzone zu erkennen (dh in einer separaten Spalte speichern).

Beispiel:Ihre lokale Zeitzone ist GMT+2. Sie speichern "2012-12-25 10:00:00 UTC". Der in der Datenbank gespeicherte aktuelle Wert ist "2012-12-25 12:00:00". Sie rufen es erneut ab:Sie erhalten es wieder als "2012-12-25 10:00:00 UTC" (aber nur, wenn Sie es mit getTimestamp(..) abrufen ), aber wenn eine andere Anwendung auf die Datenbank in der Zeitzone GMT+0 zugreift, ruft sie den Zeitstempel als „2012-12-25 12:00:00 UTC“ ab.

Wenn Sie es in einer anderen Zeitzone speichern möchten, müssen Sie den setTimestamp(int parameterIndex, Timestamp x, Calendar cal) verwenden mit einer Kalenderinstanz in der erforderlichen Zeitzone. Stellen Sie nur sicher, dass Sie beim Abrufen von Werten auch den entsprechenden Getter mit derselben Zeitzone verwenden (wenn Sie einen TIMESTAMP verwenden ohne Zeitzoneninformationen in Ihrer Datenbank).

Angenommen, Sie möchten die tatsächliche GMT-Zeitzone speichern, müssen Sie Folgendes verwenden:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
stmt.setTimestamp(11, tsSchedStartTime, cal);

Mit JDBC 4.2 sollte ein kompatibler Treiber java.time.LocalDateTime unterstützen (und java.time.LocalTime ) für TIMESTAMP (und TIME ) durch get/set/updateObject . Die java.time.Local* Klassen sind ohne Zeitzonen, daher muss keine Konvertierung angewendet werden (obwohl dies zu einer Reihe neuer Probleme führen könnte, wenn Ihr Code eine bestimmte Zeitzone annimmt).