https://blog.csdn.net/yjgithub/article/details/80404002
https://www.cnblogs.com/drizzlewithwind/p/6228001.html
背景:
centos 東8區 CST
mysql客戶端ok,jdbctemplate寫入ok
mybatis查詢差14小時
mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | CST | | time_zone | SYSTEM | +------------------+--------+ 2 rows in set (0.02 sec)
mysql> select now(); +---------------------+ | now() | +---------------------+ | 2016-12-27 22:29:59 | +---------------------+ 1 row in set (0.00 sec)
出錯過程復盤:
現在開始調試mybatis源碼,調試到mysql-connector-java-6.0.4.jar包的com.mysql.cj.jdbc.io.JdbcTimestampValueFactory的createFromTimestamp方法時,發現mysql的底層驅動程序對從數據庫查詢出來的時間用了一個Calender做類型轉換,Calender記錄中包含的時區為CST,跟中國的時區Asia/Shanghai正好差了14小時。
那么為什么mybatis連接數據庫會使用CST的美國時間呢?繼續查看源碼發現
mysql連接數據庫的時候會從mysql讀取系統的時區設置,調試com.mysql.cj.mysqla.MysqlaSession.java的configureTimezone方法發現,this.getServerVariable(“system_time_zone”)從系統里面讀出來的時區設置是CST
就少14小時。這是因為:在解析成預編譯語句的時候,誤將CST(China Standard Time utc+8)解析成CST(Central Standard Tim UTC-6),美國中部標准時間,所以少14個小時。
個人推測:
jdbctemplate認為System 的timezone CST是China Standard Time,所以寫入沒錯
mybatis的查詢認為Central Standard Time,所以查詢快了14小時
解決方案:
1. 命令修改(重啟mysql后失效)
mysql> set time_zone = '+8:00'; Query OK, 0 rows affected (0.00 sec) mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | CST | | time_zone | +08:00 | +------------------+--------+ 2 rows in set (0.04 sec)
2. 修改配置文件my.cnf(在/etc/my.cnf或者/etc/mysql/my.cnf)
default-time-zone=timezone
default-time-zone = '+8:00'
$ service mysql start