背景
今天早上剛上班,就被同事提示,程序的日期處理有問題。數據庫里日期為:2019-05-21 11:00:00 而前端顯示的日期為:2019-05-21 16:00:00
分析
那肯定是和時區相關了,別問為什么,這是程序猿該有的直覺。
首先,看一下mysql的時區是什么?
命令:show variables like '%time_zone%';
結果:
| Variable_name | Value |
|---|---|
| system_time_zone | CST |
| time_zone | SYSTEM |
那么CST時區究竟是什么時區呢,我們下面簡單介紹一下:
CST 的時區是一個很混亂的時區,有四種含義:
- 美國中部時間 Central Standard Time (USA) UTC-06:00
- 澳大利亞中部時間 Central Standard Time (Australia) UTC+09:30
- 中國標准時 China Standard Time UTC+08:00
- 古巴標准時 Cuba Standard Time UTC-04:00
今天是“4月28日”。為什么提到日期?因為美國從“3月11日”至“11月7日”實行夏令時,美國中部時間改為 UTC-05:00,與 UTC+08:00 相差 13 小時。
JDBC與MySQL開始建立連接時,在配置時區的時候,會拿到MySQL的時區是CST,然后Java 會誤以為是 CST -0500,而非 CST +0800。
正是因為這個原因,所以導致時間出現問題:16:00:00減去5個小時,正好是11:00:00
解決方案
1、不動mysql數據庫的時區的前提下
將項目的時區設置為世界標准時區UTC
在mysql的連接url上加上UTC時區
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mccs?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC
可能有些同學會疑惑,為什么不設置為中國的時區(上海),其實呢,是可以的,但是單單只設置項目的時區是不行的,我們下面看看:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mccs?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
返回給前端的日期為:2019-05-21 03:00:00。因為我們的時區是CST +0800。所以11:00:00減去8個小時候就是03:00:00了。
那么可以看出,單單設置項目的時區為中國時區是不行的。那么有什么補救方法呢?
如果對日期的格式化你是用的是jackson,那么再加多一條配置,就可以了:
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
2、直接修改mysql數據的時區
直接修改mysql數據庫的時區是最徹底的,之后所有的項目都不用管時區的問題了。
方式一:命令修改
set global time_zone = '+8:00'; ##修改mysql全局時區為北京時間,即我們所在的東8區
set time_zone = '+8:00'; ##修改當前會話時區
flush privileges; #立即生效
方式二:修改配置文件【linux:my.cnf,windows:my.ini】
在[mysqld]區域中加上:default-time_zone = '+8:00'
最后記得重啟MySQL的服務。
