簡體   English   中英

如何獲取當前本地時間的 UTC 轉換 Java 時間戳?

[英]How can I get the UTC-converted Java timestamp of current local time?

有人可以幫忙獲取當前本地時間的 UTC 轉換 Java 時間戳嗎? 主要目標是獲取當前日期和時間,轉換為 UTC 時間戳,然后作為時間戳yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]存儲在 Ignite 緩存中。

我的嘗試是Timestamp.from(Instant.now()) 但是,它仍然考慮我的本地時區+03:00 結果我得到'2020-02-20 10:57:56'而不是理想的'2020-02-20 07:57:56'

如何獲得 UTC 轉換的時間戳?

你可以這樣做:

LocalDateTime localDateTime = Instant.now().atOffset(ZoneOffset.UTC).toLocalDateTime();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
    System.out.println(localDateTime.format(formatter));

不要使用時間戳

您很可能不需要Timestamp 這很好,因為Timestamp類設計得很差,確實是在已經設計得很差的Date類之上的真正黑客。 這兩個類也早已過時。 相反,大約 6 年前,我們得到了 java.time,現代 Java 日期和時間 API。 從 JDBC 4.2 開始,這也適用於您的 JDBC 驅動程序,也適用於您的現代 JPA 實現。

使用偏移日期時間

對於時間戳,數據庫中推薦的數據類型是timestamp with time zone 在這種情況下,在 Java 中使用偏移量為零的OffsetDateTime (即 UTC)。 例如:

    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
    System.out.println(now);

    PreparedStatement statement = yourDatabaseConnection
            .prepareStatement("insert into your_table (tswtz) values (?);");
    statement.setObject(1, now);
    int rowsInserted = statement.executeUpdate();

剛才System.out.println()輸出示例:

2020-02-22T13:04:06.320Z

或者如果您的數據庫時間戳沒有時區,則使用 LocalDateTime

從你的問題我得到的印象是你的數據庫中的數據類型是沒有時區的timestamp 這只是第二好的選擇,但您可以將LocalDateTime傳遞給它。

    LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);

其余的和以前一樣。 示例輸出:

2020-02-22T13:05:08.776

如果你確實需要一個老式的 java.sql.Timestamp

您要求使用 UTC 的Timestamp Timestamp始終采用 UTC。 更准確地說,它是一個獨立於時區的時間點,因此將其轉換為不同的時區是沒有意義的。 在內部,它被實現為自紀元以來的毫秒數和納秒數。 紀元被定義為UTC 中的 1970 年的第一個時刻。

但是Timestamp類是一個令人困惑的類。 可能讓您感到困惑的一件事是當您打印它時,從而隱式調用其toString方法。 toString方法使用 JVM 的默認時區來呈現字符串,因此以本地時區打印時間。 令人困惑。 如果您在 SQL 中的數據類型是沒有時區的timestamp ,那么您的 JDBC 驅動程序很可能會將您所在時區中的Timestamp解釋為 SQL timestamp 在您的情況下這是不正確的,因為您的數據庫使用 UTC(推薦做法)。 我可以想到三種可能的解決方案:

  1. 某些數據庫引擎允許您在會話中設置時區。 我自己沒有任何經驗,這是我讀過的; 但它可能會強制執行從 Java Timestamp到 UTC 中的 SQL timestamp的正確轉換。
  2. 您可以在 Java 中進行不正確的轉換,以補償在 Java 和 SQL 之間執行的相反的錯誤轉換。 這是一個 hack,不是我想在我的代碼中包含的東西。 我把它作為最后的手段。

     LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC); Timestamp ts = Timestamp.valueOf(now); System.out.println(ts);

    2020-02-22 13:05:08.776

    您注意到它似乎只與上面的 UTC 時間一致。 這與您從 Vipin Sharma 的答案中得到的結果相同,除了 (1) 我的代碼更簡單和 (2) 您獲得了更高的精度,包括秒的分數。

  3. 數據庫是否以 UTC 格式生成當前時間戳,而不是用 Java 生成它。

鏈接

盡管Ignite 文檔說你可以在 24 小時內通過。 文檔說yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]所以你可能想在你的代碼中使用它來格式化你的日期,但這會導致中午之后的時間出錯。 相反,請使用yyyy-MM-dd HH:mm:ss[.nnnnnnnnn]格式化您的日期。

注意大寫的HH 如果您使用ZonedDateTime或 Joda 的DateTime現在使用 UTC now(UTC)調用,然后toString("yyyy-MM-dd HH:mm:ss")將以 UTC 存儲正確的時間。

暫無
暫無

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

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