簡體   English   中英

在Oracle JDBC驅動程序中,將Java日期寫入TIMESTAMP列時,時區會發生什么?

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

我已經四處尋找,但令人驚訝的是無法為Oracle JDBC找到答案。 這個密切相關的問題有PostgreSQL和MySQL的答案。

基本上,如果我在兩個不同時區有兩個應用服務器將時間戳寫入一個Oracle數據庫,會發生什么? 謝謝。

編輯:我應該補充一點,當我查詢時,JDBC似乎是發送到數據庫的值是在我的本地時區。

我整理了一些測試JDBC代碼,以確切了解發生了什么。 結果很有趣。 Oracle有三種密切相關的數據類型: TIMESTAMPTIMESTAMP WITH TIME ZONETIMESTAMP WITH LOCAL TIME ZONE 我使用完全相同的代碼,並從兩個不同的框中運行它,一個在“America / New_York”時區,一個在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
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM