1. 程式人生 > >帶有時區資訊的java與js解決經驗

帶有時區資訊的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時區,在程式中做相關處理。

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