[英]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
從你的問題我得到的印象是你的數據庫中的數據類型是沒有時區的timestamp
。 這只是第二好的選擇,但您可以將LocalDateTime
傳遞給它。
LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
其余的和以前一樣。 示例輸出:
2020-02-22T13:05:08.776
您要求使用 UTC 的Timestamp
。 Timestamp
始終采用 UTC。 更准確地說,它是一個獨立於時區的時間點,因此將其轉換為不同的時區是沒有意義的。 在內部,它被實現為自紀元以來的毫秒數和納秒數。 紀元被定義為UTC 中的 1970 年的第一個時刻。
但是Timestamp
類是一個令人困惑的類。 可能讓您感到困惑的一件事是當您打印它時,從而隱式調用其toString
方法。 toString
方法使用 JVM 的默認時區來呈現字符串,因此以本地時區打印時間。 令人困惑。 如果您在 SQL 中的數據類型是沒有時區的timestamp
,那么您的 JDBC 驅動程序很可能會將您所在時區中的Timestamp
解釋為 SQL timestamp
。 在您的情況下這是不正確的,因為您的數據庫使用 UTC(推薦做法)。 我可以想到三種可能的解決方案:
Timestamp
到 UTC 中的 SQL timestamp
的正確轉換。您可以在 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) 您獲得了更高的精度,包括秒的分數。
盡管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.