Oracle
 sql >> Database >  >> RDS >> Oracle

Nel driver Oracle JDBC, cosa succede al fuso orario quando scrivi una data Java in una colonna TIMESTAMP?

Ho messo insieme del codice JDBC di prova per capire esattamente cosa succede. I risultati sono stati interessanti. Oracle ha tre tipi di dati strettamente correlati:TIMESTAMP , TIMESTAMP WITH TIME ZONE e TIMESTAMP WITH LOCAL TIME ZONE . Ho preso lo stesso identico codice e l'ho eseguito da due caselle diverse, una nel fuso orario "America/New_York" e una in esecuzione su UTC. Entrambi hanno raggiunto lo stesso database, in esecuzione in UTC. Stavo usando il driver Oracle 11.2.0.2.0.

  • Il TIMESTAMP colonna è stata impostata su qualunque fosse l'ora locale sulla macchina che esegue il codice Java. Non è stata eseguita alcuna traduzione del fuso orario.
  • Il TIMESTAMP WITH TIME ZONE colonna ha tradotto l'ora nel fuso orario in cui si trovava il client JDBC.
  • Il TIMESTAMP WITH LOCAL TIME ZONE colonna ha anche tradotto l'ora nel fuso orario in cui si trovava il client JDBC.

Questo articolo , che è un po' più vecchio, indica che TIMESTAMP WITH TIME ZONE è praticamente inutile se vuoi fare qualcosa come indici o partizioni. Tuttavia, sembra TIMESTAMP WITH LOCAL TIME ZONE potrebbe essere estremamente utile. (Non sono sicuro di cosa succede se si modifica il fuso orario del server, ma sembra essere intelligente sui fusi orari locali dei client JDBC). Non ho avuto la possibilità di testare il comportamento di indicizzazione, ecc. con questi tipi di dati.

Incolla nella mia classe di esempio di seguito se desideri riprodurre i miei test nel tuo 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
            }
        }
    }
}