日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

什么比日期和时区更难? SQL / JDBC中的日期和时区!

發布時間:2023/12/3 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 什么比日期和时区更难? SQL / JDBC中的日期和时区! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在jOOQ郵件列表上,最近有一個有趣的討論,關于jOOQ當前缺乏對TIMESTAMP WITH TIME ZONE數據類型的現成支持。

沒有人說日期,時間和時區很容易! 這里有一個有趣的部分,我建議閱讀: 虛假的程序員相信時間

當那還不夠時,還請閱讀: 更多的虛假程序員相信時間

我個人喜歡程序員錯誤地認為“ Unix時間是自1970年1月1日以來的秒數”。 …Unix時間無法代表leap秒;)

返回JDBC

這是Jaybird開發人員(Firebird JDBC驅動程序) Mark Rotteveel提出的一個有趣的Stack Overflow答案: java.sql.Timestamp時區是否特定?

可以按照以下方式觀察Mark的解釋(我在這里使用PostgreSQL):

Connection c = getConnection(); Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));try (PreparedStatement ps = c.prepareStatement("select"+ " ?::timestamp,"+ " ?::timestamp,"+ " ?::timestamp with time zone,"+ " ?::timestamp with time zone" )) {ps.setTimestamp(1, new Timestamp(0));ps.setTimestamp(2, new Timestamp(0), utc);ps.setTimestamp(3, new Timestamp(0));ps.setTimestamp(4, new Timestamp(0), utc);try (ResultSet rs = ps.executeQuery()) {rs.next();System.out.println(rs.getTimestamp(1) + " / " + rs.getTimestamp(1).getTime());System.out.println(rs.getTimestamp(2, utc)+ " / " + rs.getTimestamp(2, utc).getTime());System.out.println(rs.getTimestamp(3) + " / " + rs.getTimestamp(3).getTime());System.out.println(rs.getTimestamp(4, utc)+ " / " + rs.getTimestamp(4, utc).getTime());} }

上面的程序使用Java和DB中使用時區而不使用時區的所有排列,并且輸出始終相同:

1970-01-01 01:00:00.0 / 0 1970-01-01 01:00:00.0 / 0 1970-01-01 01:00:00.0 / 0 1970-01-01 01:00:00.0 / 0

如您所見,在每種情況下,UTC時間戳0均已正確存儲并從數據庫中檢索到。 我自己的語言環境是瑞士,即CET / CEST,在Epoch是UTC + 1,這就是在Timestamp.toString()上獲取輸出的地方。

當您在SQL和/或Java中使用時間戳文字時,事情會變得很有趣。 如果這樣替換綁定變量:

Timestamp almostEpoch = Timestamp.valueOf("1970-01-01 00:00:00");ps.setTimestamp(1, almostEpoch); ps.setTimestamp(2, almostEpoch, utc); ps.setTimestamp(3, almostEpoch); ps.setTimestamp(4, almostEpoch, utc);

這又是我在CET / CEST上獲得的東西

1970-01-01 00:00:00.0 / -3600000 1970-01-01 00:00:00.0 / -3600000 1970-01-01 00:00:00.0 / -3600000 1970-01-01 00:00:00.0 / -3600000

即不是Epoch,而是我首先發送到服務器的時間戳文字。 請注意,綁定/獲取的四種組合仍然始終產生相同的時間戳。

讓我們看看如果寫入數據庫的會話使用與從數據庫中獲取會話不同的時區(假設您在PST中)(我再次使用CET或UTC),會發生什么情況。 我正在運行此程序:

Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));Calendar pst = Calendar.getInstance(TimeZone.getTimeZone("PST"));try (PreparedStatement ps = c.prepareStatement("select"+ " ?::timestamp,"+ " ?::timestamp,"+ " ?::timestamp with time zone,"+ " ?::timestamp with time zone" )) {ps.setTimestamp(1, new Timestamp(0), pst);ps.setTimestamp(2, new Timestamp(0), pst);ps.setTimestamp(3, new Timestamp(0), pst);ps.setTimestamp(4, new Timestamp(0), pst);try (ResultSet rs = ps.executeQuery()) {rs.next();System.out.println(rs.getTimestamp(1)+ " / " + rs.getTimestamp(1).getTime());System.out.println(rs.getTimestamp(2, utc)+ " / " + rs.getTimestamp(2, utc).getTime());System.out.println(rs.getTimestamp(3)+ " / " + rs.getTimestamp(3).getTime());System.out.println(rs.getTimestamp(4, utc)+ " / " + rs.getTimestamp(4, utc).getTime());} }

它產生以下輸出:

1969-12-31 16:00:00.0 / -32400000 1969-12-31 17:00:00.0 / -28800000 1970-01-01 01:00:00.0 / 0 1970-01-01 01:00:00.0 / 0

第一個時間戳記是將Epoch存儲為PST(16:00),然后數據庫中刪除了時區信息,這將Epoch變成了您在Epoch處的本地時間(-28800秒/ -8h),即真正存儲。

現在,當我從自己的時區CET獲取該時間時,我仍然想要獲取當地時間(16:00)。 但是在我的時區中,這不再是-28800秒,而是-32400秒(-9h)。 夠古怪嗎?

當我獲取存儲的本地時間(16:00)時,事情發生了相反的變化,但是我強迫獲取發生在UTC中,這將產生您存儲的時間戳,最初是PST(-28800)秒)。 但是,在我的時區CET中打印此時間戳(-28800秒)時,現在是17:00。

當我們在數據庫中使用TIMESTAMP WITH TIME ZONE數據類型時,將保持時區(PST),并且當我獲取Timestamp值時,無論使用CET還是UTC,我仍然會得到Epoch,它已安全地存儲到了數據庫,在CET中打印為01:00。

ew。

TL; DR:

使用jOOQ時 ,如果正確的UTC時間戳對您很重要,請使用TIMESTAMP WITH TIMEZONE,但是您必須實現自己的數據類型Binding ,因為jOOQ當前不支持該數據類型。 一旦使用了自己的數據類型Binding,就可以使用Java 8的time API,它比java.sql.Timestamp +丑陋的Calendar更好地表示了這些不同的類型。

如果當地時間對您很重要,或者您不在跨時區工作,則可以使用TIMESTAMP和jOOQ的Field <Timestamp>。

幸運的是,如果您像我一樣,可以在一個只有一個時區的很小的國家/地區進行操作,而大多數本地軟件都不會遇到此問題。

翻譯自: https://www.javacodegeeks.com/2015/07/whats-even-harder-than-dates-and-timezones-dates-and-timezones-in-sql-jdbc.html

總結

以上是生活随笔為你收集整理的什么比日期和时区更难? SQL / JDBC中的日期和时区!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。