Reuní un código JDBC de prueba para averiguar exactamente qué sucede. Los resultados fueron interesantes. Oracle tiene tres tipos de datos estrechamente relacionados:TIMESTAMP
, TIMESTAMP WITH TIME ZONE
y TIMESTAMP WITH LOCAL TIME ZONE
. Tomé exactamente el mismo código y lo ejecuté desde dos cuadros diferentes, uno en la zona horaria "América/Nueva_York" y otro en UTC. Ambos acceden a la misma base de datos, ejecutándose en UTC. Estaba usando el controlador Oracle 11.2.0.2.0.
- El
TIMESTAMP
la columna se configuró en la hora local que fuera en la máquina que ejecutaba el código Java. No se realizó ninguna conversión de zona horaria. - El
TIMESTAMP WITH TIME ZONE
columna tradujo la hora a la zona horaria en la que se encontraba el cliente JDBC. - El
TIMESTAMP WITH LOCAL TIME ZONE
columna también tradujo la hora a la zona horaria en la que se encontraba el cliente JDBC.
Este artículo
, que es un poco más antiguo, indica que TIMESTAMP WITH TIME ZONE
es bastante inútil si quieres hacer algo como índices o particiones. Sin embargo, parece que TIMESTAMP WITH LOCAL TIME ZONE
podría ser extremadamente útil. (No estoy seguro de qué sucede si cambia la zona horaria del servidor, pero parece ser inteligente acerca de las zonas horarias locales de los clientes JDBC). No he tenido la oportunidad de probar el comportamiento de indexación, etc. con estos tipos de datos.
Pegando mi clase de muestra a continuación si desea reproducir mis pruebas en su entorno.
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
}
}
}
}