![](/img/trans.png)
[英]Before writing a Java Date to an SQL TIMESTAMP column, does JDBC translate the date from the JVM time zone to the database session time zone?
[英]In the Oracle JDBC driver, what happens to the time zone when you write a Java date to a TIMESTAMP column?
我已經四處尋找,但令人驚訝的是無法為Oracle JDBC找到答案。 這個密切相關的問題有PostgreSQL和MySQL的答案。
基本上,如果我在兩個不同時區有兩個應用服務器將時間戳寫入一個Oracle數據庫,會發生什么? 謝謝。
編輯:我應該補充一點,當我查詢時,JDBC似乎是發送到數據庫的值是在我的本地時區。
我整理了一些測試JDBC代碼,以確切了解發生了什么。 結果很有趣。 Oracle有三種密切相關的數據類型: TIMESTAMP
, TIMESTAMP WITH TIME ZONE
和TIMESTAMP WITH LOCAL TIME ZONE
。 我使用完全相同的代碼,並從兩個不同的框中運行它,一個在“America / New_York”時區,一個在UTC上運行。 兩者都以UTC格式運行相同的數據庫。 我使用的是Oracle 11.2.0.2.0驅動程序。
TIMESTAMP
列設置為執行Java代碼的機器上的本地時間。 沒有執行時區轉換。 TIMESTAMP WITH TIME ZONE
列將時間轉換為JDBC客戶端所在的任何時區。 TIMESTAMP WITH LOCAL TIME ZONE
列還將時間轉換為JDBC客戶端所在的任何時區。 這篇文章有點舊,表明如果你想做索引或分區之類的事情, TIMESTAMP WITH TIME ZONE
幾乎沒用。 但是,似乎TIMESTAMP WITH LOCAL TIME ZONE
可能非常有用。 (不確定如果更改服務器的時區會發生什么,但它似乎對JDBC客戶端的本地時區是智能的)。 我沒有機會用這些數據類型測試索引行為等。
如果您想在您的環境中重現我的測試,請在下面的示例類中粘貼。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Date;
// create table x_tst_ts_tab(
// os_name varchar(256)
// ts timestamp,
// ts_with_tz timestamp with time zone,
// ts_with_local_tz timestamp with local time zone
// )
class TSTest {
public static final void main(String[] argv) throws Exception {
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection(
"your_connection_string",
"your_user_name",
"your_password");
try {
// Insert some data
Date nowDate = new Date();
Timestamp nowTimestamp = new Timestamp(nowDate.getTime());
PreparedStatement insertStmt = conn.prepareStatement(
"INSERT INTO x_tst_ts_tab"
+ " (os_name, ts, ts_with_tz, ts_with_local_tz)"
+ " VALUES (?, ?, ?, ?)");
try {
insertStmt.setString(1, System.getProperty("os.name"));
insertStmt.setTimestamp(2, nowTimestamp);
insertStmt.setTimestamp(3, nowTimestamp);
insertStmt.setTimestamp(4, nowTimestamp);
insertStmt.executeUpdate();
} finally {
try {
insertStmt.close();
} catch (Throwable t) {
// do nothing
}
}
System.out.println("os_name, ts, ts_with_tz, ts_with_local_tz");
// Read back everything in the DB
PreparedStatement selectStmt = conn.prepareStatement(
"SELECT os_name, ts, ts_with_tz, ts_with_local_tz"
+ " FROM dom_fraud_beacon.x_tst_ts_tab");
ResultSet result = null;
try {
result = selectStmt.executeQuery();
while (result.next()) {
System.out.println(
String.format("%s,%s,%s,%s",
result.getString(1),
result.getTimestamp(2).toString(),
result.getTimestamp(3).toString(),
result.getTimestamp(4).toString()
));
}
} finally {
try {
result.close();
} catch (Throwable t) {
// do nothing
} finally {
try {
selectStmt.close();
} catch (Throwable t) {
// do nothing
}
}
}
} finally {
try {
conn.close();
} catch (Throwable t) {
// do nothing
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.