Zebrałem trochę testowego kodu JDBC, aby dowiedzieć się, co się dokładnie dzieje. Wyniki były interesujące. Oracle ma trzy ściśle powiązane typy danych:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
i TIMESTAMP WITH LOCAL TIME ZONE
. Wziąłem dokładnie ten sam kod i uruchomiłem go z dwóch różnych skrzynek, jednego w strefie czasowej „Ameryka/Nowy_Jork”, a drugiego działającego w UTC. Oba trafiły do tej samej bazy danych, działającej w UTC. Używałem sterownika Oracle 11.2.0.2.0.
TIMESTAMP
kolumna została ustawiona na dowolny czas lokalny na komputerze wykonującym kod Java. Nie wykonano tłumaczenia stref czasowych.TIMESTAMP WITH TIME ZONE
kolumna przetłumaczyła czas na dowolną strefę czasową, w której znajdował się klient JDBC.TIMESTAMP WITH LOCAL TIME ZONE
kolumna przetłumaczyła również czas na dowolną strefę czasową, w której znajdował się klient JDBC.
Ten artykuł
, który jest nieco starszy, wskazuje, że TIMESTAMP WITH TIME ZONE
jest prawie bezużyteczny, jeśli chcesz zrobić coś takiego jak indeksy lub partycje. Wygląda jednak na to, że TIMESTAMP WITH LOCAL TIME ZONE
może być niezwykle przydatne. (Nie jestem pewien, co się stanie, jeśli zmienisz strefę czasową serwera, ale wydaje się, że jest inteligentny w odniesieniu do lokalnych stref czasowych klientów JDBC). Nie miałem okazji przetestować zachowania indeksowania itp. z tymi typami danych.
Wklejam poniżej moją przykładową klasę, jeśli chcesz odtworzyć moje testy w swoim środowisku.
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
}
}
}
}