Dal jsem dohromady nějaký testovací kód JDBC, abych přesně zjistil, co se stane. Výsledky byly zajímavé. Oracle má tři úzce související datové typy:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
a TIMESTAMP WITH LOCAL TIME ZONE
. Vzal jsem přesně stejný kód a spustil ho ze dvou různých polí, jednoho v časovém pásmu „Amerika/New_York“ a jednoho běžícího na UTC. Oba zasáhli stejnou databázi běžící v UTC. Používal jsem ovladač Oracle 11.2.0.2.0.
TIMESTAMP
sloupec byl nastaven na libovolný místní čas na počítači spouštějícím kód Java. Nebyl proveden žádný překlad časového pásma.TIMESTAMP WITH TIME ZONE
sloupec převedl čas do jakéhokoli časového pásma, ve kterém se klient JDBC nacházel.TIMESTAMP WITH LOCAL TIME ZONE
sloupec také přeložil čas do jakéhokoli časového pásma, ve kterém se klient JDBC nacházel.
Tento článek
, který je o něco starší, označuje, že TIMESTAMP WITH TIME ZONE
je v podstatě k ničemu, pokud chcete dělat něco jako indexy nebo oddíly. Zdá se však, že TIMESTAMP WITH LOCAL TIME ZONE
může být velmi užitečné. (Nejsem si jistý, co se stane, když změníte časové pásmo serveru, ale zdá se, že je to inteligentní ohledně místních časových pásem klientů JDBC). S těmito datovými typy jsem neměl možnost otestovat chování indexování atd.
Vložení do mé ukázkové třídy níže, pokud chcete mé testy reprodukovat ve vašem prostředí.
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
}
}
}
}