現象
問題描述:頁面時間和數據庫時間相差13小時。
排坑過程
被轉換的日期屬性:用的就是jackson的日期轉換成字符串。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastLoginTime;
一、添加jackson時區配置
網上說是jackson轉換時區問題,隨后加上了
yml配置:
spring:
jackson:
time-zone: GMT+8
測試后,仍然沒有解決問題。
二、數據庫時區設置
排查后發現java服務拿到日期的時候已經錯誤了,並不是jackson轉化的時候出現的問題。
我存在mysql中的類型是timestamp,先看下timestamp的特點
- 值以UTC格式保存( it stores the number of milliseconds)
- 與時區有關,存儲的時候根據數據庫配置的時區進行轉化為UTC時間,取的時候把UTC時間轉成數據庫配置時區的時間。
再看下mysql驅動(mysql-connector)中獲取時區的方法。
String configuredTimeZoneOnServer = this.serverSession.getServerVariable("time_zone"); if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) { configuredTimeZoneOnServer = this.serverSession.getServerVariable("system_time_zone"); }
查看mysql時區的配置
show variables like '%time_zone%';
根據上面代碼,time_zone=='SYSTEM'的時候取system_time_zone的值
system_time_zone的值為CST
坑
CST在數據庫中是中國標准時間的意思,但是與jdbc轉化的時候把它當成了美國中部時間,這2個時區都叫CST。
這個美國中部時間在夏令時=UTC-5,上海時區=UTC+8,所以出現了和數據庫時間差13小時的現象。(冬令時差14小時)。
解決
直接設置數據庫的time_zone這樣mysql驅動就不會讀到system_time_zone
set global time_zone='+8:00'; set time_zone = '+8:00'; flush privileges;
時區設置也可以通過修改mysql配置實現,修改 my.cnf
文件,在[mysqld]
節下增加 default-time-zone = '+08:00'。