在Oracle JDBC驱动程序,当你写一个Java日期到TIMESTAMP列发生了什么时区?(In

2019-06-27 03:35发布

我四处搜寻,令人惊奇找不到甲骨文JDBC的答案。 此密切相关的问题,对PostgreSQL和MySQL的答案。

基本上,如果我有两个不同的时区写入时间戳一个Oracle数据库的两个应用程序服务器,会发生什么? 谢谢。

编辑:我要补充,这似乎像JDBC被发送到数据库时,我做的查询是在我的本地时区的价值。

Answer 1:

我把一些测试JDBC代码,以弄清楚到底发生了什么。 结果很有趣。 Oracle有三个密切相关的数据类型: TIMESTAMPTIMESTAMP WITH TIME ZONETIMESTAMP WITH LOCAL TIME ZONE 。 我采取了完全相同的代码,并从两个不同的盒子,一个在“美国/纽约”时区,并在UTC一个人跑来跑去了。 双双创下同一个数据库中,UTC运行。 我使用Oracle 11.2.0.2.0驱动程序。

  • TIMESTAMP列设置为任何本地时间执行Java代码的机器上。 未进行时区转换。
  • TIMESTAMP WITH TIME ZONE列转换到任何时区的JDBC客户端是时间。
  • TIMESTAMP WITH LOCAL TIME ZONE列也翻译成任何时区的JDBC客户端是时间。

这篇文章 ,这是一个年纪大一点,表明TIMESTAMP WITH TIME ZONE几乎是无用的,如果你想要做像索引或分区的任何东西。 然而,这似乎是TIMESTAMP WITH LOCAL TIME ZONE可能是非常有用的。 (不知道如果你改变了服务器的时区,但它似乎是聪明的有关JDBC客户端的本地时区会发生什么)。 我还没有机会测试索引行为等这些数据类型。

粘贴在下面,如果你想重现我的测试环境中的我的示例类。

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


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