問題
Java后台程序讀取數據庫時間,在前端頁面進行展示的時候,出現了錯誤,展示的時間和數據庫中的時間不一致。
所用工具及其版本如下
- Mysql 數據庫版本: 8.0.15 for osx 10.14
- 數據庫里的時間類型: dateTime
- JDK版本:11.0.2
- Mysql 驅動:mysql-connector-java 8.0.16
- 數據源:com.alibaba.druid 1.1.19
- Java 項目里,時間類型:joda-time 2.10.2 的 DateTime
排查原因
最開始排查原因,是不是從數據庫讀取時間之后進行轉化出錯了,因為為了在前端進行時間展示,我將數據庫讀取出來的時間先轉化為了字符串,再轉化為DateTime的時間格式。開始進行測試:
1 DateTime now = DateTime.now(); 2 System.out.println(now); 3
4 String nowStr = now.toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")); 5 System.out.println(nowStr);
輸出為:
1 2019-09-03T11:15:23.749+08:00
2 2019-09-03 11:15:23
可以看到 DateTime 的輸出時間格式是很標准的,后面還加上了“+08:00”,代表了東八區北京時間。轉化為字符串的顯示也是正確的。
下一步排查數據庫的讀取是否正確,在終端進入數據庫,發現數據庫里的時間和終端讀取出來的時間一致。
那看來只能是項目代碼從數據庫中讀取數據出錯了。將時間信息反復修改觀察程序讀取出來的時間信息,發現程序讀取出來的時間是種要比數據庫寫入的時間多 13 小時。整整 13 小時。這是什么原因,就算是用的格林威治標准時間那也應該差 8 小時或者 15 小時吧,這個 13 小時是個什么原因。難道是和西五區時間做了計算嗎?
再在網上搜索一下,最后在這篇文章中找到了答案。原因就是Java和Mysql協商時區時把 Mysql 的 CST 時間以美國中部時間:UTC-5 當做標准,而我們用的是東八區的北京時間 UTC+5,所以我從數據庫中讀取的 UTC-5 時間到了Java 程序里就自動轉化為 UTC+8 時間,也就比數據庫里的時間多了 13 個小時。
解決方法
在數據庫配置文件里面,在連接字符串中設置時區:
1 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/yourDB?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8。
這樣程序在從數據庫讀取時間的時候,時間默認就是使用的東八區的時間,而不是使用數據庫的西五區時間了。