Oracle
 sql >> Base de données >  >> RDS >> Oracle

Dans le pilote Oracle JDBC, qu'advient-il du fuseau horaire lorsque vous écrivez une date Java dans une colonne TIMESTAMP ?

J'ai rassemblé du code JDBC de test pour comprendre exactement ce qui se passe. Les résultats étaient intéressants. Oracle a trois types de données étroitement liés :TIMESTAMP , TIMESTAMP WITH TIME ZONE , et TIMESTAMP WITH LOCAL TIME ZONE . J'ai pris exactement le même code et l'ai exécuté à partir de deux boîtes différentes, une dans le fuseau horaire "America/New_York" et une fonctionnant sur UTC. Les deux frappent la même base de données, fonctionnant en UTC. J'utilisais le pilote Oracle 11.2.0.2.0.

  • Le TIMESTAMP colonne a été définie sur l'heure locale de la machine exécutant le code Java. Aucune conversion de fuseau horaire n'a été effectuée.
  • Le TIMESTAMP WITH TIME ZONE la colonne a traduit l'heure dans le fuseau horaire dans lequel se trouvait le client JDBC.
  • Le TIMESTAMP WITH LOCAL TIME ZONE la colonne traduisait également l'heure dans le fuseau horaire dans lequel se trouvait le client JDBC.

Cet article , qui est un peu plus ancien, indique que TIMESTAMP WITH TIME ZONE est à peu près inutile si vous voulez faire quelque chose comme des index ou des partitions. Cependant, il semble que TIMESTAMP WITH LOCAL TIME ZONE pourrait être extrêmement utile. (Vous ne savez pas ce qui se passe si vous modifiez le fuseau horaire du serveur, mais il semble être intelligent sur les fuseaux horaires locaux des clients JDBC). Je n'ai pas eu l'occasion de tester le comportement d'indexation, etc. avec ces types de données.

Collez mon exemple de classe ci-dessous si vous souhaitez reproduire mes tests dans votre environnement.

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
            }
        }
    }
}