Ik heb wat JDBC-testcode samengesteld om erachter te komen wat er precies gebeurt. De resultaten waren interessant. Oracle heeft drie nauw verwante datatypes:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
, en TIMESTAMP WITH LOCAL TIME ZONE
. Ik heb exact dezelfde code genomen en deze vanuit twee verschillende vakken uitgevoerd, één in de tijdzone "America/New_York" en één op UTC. Beiden raken dezelfde database, draaiend in UTC. Ik gebruikte de Oracle 11.2.0.2.0-driver.
- De
TIMESTAMP
kolom was ingesteld op de lokale tijd op de machine die de Java-code uitvoerde. Er is geen tijdzonevertaling uitgevoerd. - De
TIMESTAMP WITH TIME ZONE
kolom vertaalde de tijd naar de tijdzone waarin de JDBC-client zich bevond. - De
TIMESTAMP WITH LOCAL TIME ZONE
column vertaalde ook de tijd naar de tijdzone waarin de JDBC-client zich bevond.
Dit artikel
, die wat ouder is, geeft aan dat TIMESTAMP WITH TIME ZONE
is vrijwel nutteloos als je iets wilt doen zoals indexen of partities. Het lijkt er echter op dat TIMESTAMP WITH LOCAL TIME ZONE
kan zeer nuttig zijn. (Ik weet niet zeker wat er gebeurt als je de tijdzone van de server verandert, maar het lijkt intelligent te zijn over de lokale tijdzones van JDBC-clients). Ik heb geen kans gehad om het indexeringsgedrag enz. met deze gegevenstypen te testen.
Plakken in mijn voorbeeldklasse hieronder als je mijn tests in je omgeving wilt reproduceren.
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
}
}
}
}