Saya mengumpulkan beberapa kode uji JDBC untuk mencari tahu apa yang sebenarnya terjadi. Hasilnya menarik. Oracle memiliki tiga tipe data yang terkait erat:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
, dan TIMESTAMP WITH LOCAL TIME ZONE
. Saya mengambil kode yang sama persis, dan menjalankannya dari dua kotak berbeda, satu di zona waktu "Amerika/New_York", dan satu lagi berjalan di UTC. Keduanya mengenai database yang sama, berjalan di UTC. Saya menggunakan driver Oracle 11.2.0.2.0.
TIMESTAMP
kolom disetel ke apa pun waktu lokal pada mesin yang mengeksekusi kode Java. Tidak ada terjemahan zona waktu yang dilakukan.TIMESTAMP WITH TIME ZONE
kolom menerjemahkan waktu ke zona waktu mana pun klien JDBC berada.TIMESTAMP WITH LOCAL TIME ZONE
kolom juga menerjemahkan waktu ke zona waktu mana pun klien JDBC berada.
Artikel ini
, yang sedikit lebih tua, menunjukkan bahwa TIMESTAMP WITH TIME ZONE
hampir tidak berguna jika Anda ingin melakukan sesuatu seperti indeks atau partisi. Namun, sepertinya TIMESTAMP WITH LOCAL TIME ZONE
mungkin sangat berguna. (Tidak yakin apa yang terjadi jika Anda mengubah zona waktu server, tetapi tampaknya cerdas tentang zona waktu lokal klien JDBC). Saya belum sempat menguji perilaku pengindeksan, dll. dengan tipe data ini.
Tempelkan di kelas sampel saya di bawah ini jika Anda ingin mereproduksi pengujian saya di lingkungan Anda.
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
}
}
}
}