Събрах тестов JDBC код, за да разбера какво точно се случва. Резултатите бяха интересни. Oracle има три тясно свързани типа данни:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
и TIMESTAMP WITH LOCAL TIME ZONE
. Взех абсолютно същия код и го пуснах от две различни кутии, едната в часовата зона "Америка/Ню_Йорк", а другата работеща по 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
}
}
}
}