Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

No driver Oracle JDBC, o que acontece com o fuso horário quando você grava uma data Java em uma coluna TIMESTAMP?


Eu montei um código JDBC de teste para descobrir exatamente o que acontece. Os resultados foram interessantes. O Oracle tem três tipos de dados intimamente relacionados:TIMESTAMP , TIMESTAMP WITH TIME ZONE e TIMESTAMP WITH LOCAL TIME ZONE . Peguei exatamente o mesmo código e o executei em duas caixas diferentes, uma no fuso horário "America/New_York" e outra em UTC. Ambos atingem o mesmo banco de dados, rodando em UTC. Eu estava usando o driver Oracle 11.2.0.2.0.
  • O TIMESTAMP A coluna foi definida para qualquer hora local na máquina que executa o código Java. Nenhuma tradução de fuso horário foi realizada.
  • O TIMESTAMP WITH TIME ZONE coluna traduziu a hora para qualquer fuso horário em que o cliente JDBC estava.
  • O TIMESTAMP WITH LOCAL TIME ZONE A coluna também traduzia a hora para qualquer fuso horário em que o cliente JDBC estava.

Este artigo , que é um pouco mais antigo, indica que TIMESTAMP WITH TIME ZONE é praticamente inútil se você quiser fazer algo como índices ou partições. No entanto, parece que TIMESTAMP WITH LOCAL TIME ZONE pode ser extremamente útil. (Não tenho certeza do que acontece se você alterar o fuso horário do servidor, mas parece ser inteligente sobre os fusos horários locais dos clientes JDBC). Eu não tive a chance de testar o comportamento de indexação, etc. com esses tipos de dados.

Colando na minha classe de exemplo abaixo se você quiser reproduzir meus testes em seu ambiente.
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
            }
        }
    }
}