In the Oracle JDBC driver, what happens to the time zone when you write a Java date to a TIMESTAMP column?

前端 未结 1 1558
遇见更好的自我
遇见更好的自我 2021-01-02 03:27

I\'ve searched around, and surprisingly can\'t find an answer to this for Oracle JDBC. This closely related question has answers for PostgreSQL and MySQL.

Basically,

相关标签:
1条回答
  • 2021-01-02 04:08

    I put together some test JDBC code to figure out exactly what happens. The results were interesting. Oracle has three closely related datatypes: TIMESTAMP, TIMESTAMP WITH TIME ZONE, and TIMESTAMP WITH LOCAL TIME ZONE. I took the exact same code, and ran it from two different boxes, one in the "America/New_York" timezone, and one running on UTC. Both hit the same database, running in UTC. I was using the Oracle 11.2.0.2.0 driver.

    • The TIMESTAMP column was set to whatever the local time was on the machine executing the Java code. No time zone translation was performed.
    • The TIMESTAMP WITH TIME ZONE column translated the time to whatever timezone the JDBC client was in.
    • The TIMESTAMP WITH LOCAL TIME ZONE column also translated the time to whatever timezone the JDBC client was in.

    This article, which is a bit older, indicates that TIMESTAMP WITH TIME ZONE is pretty much useless if you want to do anything like indexes or partitions. However, it seems like TIMESTAMP WITH LOCAL TIME ZONE might be extremely useful. (Not sure what happens if you change the server's time zone, but it seems to be intelligent about JDBC clients' local time zones). I haven't had a chance to test indexing behavior, etc. with these datatypes.

    Pasting in my sample class below if you'd like to reproduce my tests in your environment.

    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
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题