帶有時區信息的java與js解決經驗

開發項目過程中經常會出現服務器的時區設置爲UTC,而開發機則爲GMT+8的情況,這種時候,程序運行就會存在問題,比如數據的插入時間不正確,與舊系統通信時,時間戳轉化不正確等等異常情況,排查起來較爲費勁,爲了解決時區問題,在Java中,jdk8提供了java.time包的LocalDateTime和ZoneDateTime解決方案

LocalDateTime不帶有時區信息,而ZoneDateTime帶有時區信息

jshell> ZonedDateTime.now()

$6 ==> 2018-08-01T12:51:04.006387+08:00[Asia/Shanghai]

jshell> LocalDateTime.now()

$7 ==> 2018-08-01T12:51:14.459202

在jackson框架對LocalDateTime的補丁:

<dependency>
   <groupId>com.fasterxml.jackson.datatype</groupId>
   <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
下,LocalDateTime將會被解析成爲類似

"2018-08-30T11:20:20"//當服務器的時間爲GMT+8時

"2018-08-30T03:20:20"//當服務器的時間爲UTC時

而ZoneDateTime將會被解析成爲類似

"2018-08-30T11:20:20+08:00" //當服務器的時間爲GMT+8時

"2018-08-30T03:20:20Z"//當服務器的時間爲UTC時

可以看出,時間在ZoneDateTime類中將會以帶有時區信息的格式出現

 

這種數據在與前端進行交互時,一般使用Date.parse方法,如下所示:

Date.parse('2018-08-30T03:20:20Z')
1535599220000
Date.parse('2018-08-30T11:20:20+08:00')
1535599220000

var a=new Date(1535599220000)
Thu Aug 30 2018 11:20:20 GMT+0800 (中國標準時間)

可以看出來,js直接將時間轉換成了本地瀏覽器時區的時間戳。

對於LocalDateTime來說,顯示如下:

Date.parse('2018-08-30 03:20:20')
1535570420000
Date.parse('2018-08-30T03:20:20')
1535570420000

var b=new Date(1535570420000)
Thu Aug 30 2018 03:20:20 GMT+0800 (中國標準時間)

可以看出來,用LocalDateTime方式在前端parse出來,再進行new Date的對象b的時區存在問題,不能再進行時區調整。

 

所以在此推薦前後端交互時,嚴格使用帶有時區的datetimeString形如"2018-08-30T03:20:20Z",

即在java中通過ZoneDateTime進行時間相關的處理。

在數據庫中,則使用帶有時區信息的類型去處理時間,比如在postgreSQL中的timestamptz字段。MySQL中無法做時區處理,推薦使用統一時區:UTC時區,在程序中做相關處理。

如此可以省去部署過程中對機器的時區做調整的步驟。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章