Jeg sammensatte en test JDBC-kode for at finde ud af præcis, hvad der sker. Resultaterne var interessante. Oracle har tre tæt relaterede datatyper:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
, og TIMESTAMP MED LOKAL TIDZONE
. Jeg tog nøjagtig den samme kode og kørte den fra to forskellige bokse, en i "America/New_York"-tidszonen og en, der kører på UTC. Begge rammer den samme database, kører i UTC. Jeg brugte Oracle 11.2.0.2.0-driveren.
TIMESTAMP kolonne blev indstillet til, hvad den lokale tid var på den maskine, der udførte Java-koden. Der blev ikke udført nogen tidszoneoversættelse. TIDSSTAMPE MED TIDSZONE kolonne oversatte tiden til den tidszone, JDBC-klienten var i. TIMESTAMP MED LOKAL TIDZONE kolonne oversatte også tiden til den tidszone, JDBC-klienten var i.
Denne artikel
, som er lidt ældre, angiver, at TIMESTAMP WITH TIME ZONE
er stort set ubrugelig, hvis du vil gøre noget som indekser eller partitioner. Det ser dog ud til at TIMESTAMP WITH LOCAL TIME ZONE
kan være yderst nyttig. (Ikke sikker på, hvad der sker, hvis du ændrer serverens tidszone, men det ser ud til at være intelligent omkring JDBC-klienters lokale tidszoner). Jeg har ikke haft mulighed for at teste indekseringsadfærd osv. med disse datatyper.
Indsæt min prøveklasse nedenfor, hvis du gerne vil gengive mine tests i dit miljø.
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
}
}
}
}