關於Mysql6.0+的時區錯亂問題


如果使用mysql6.0+的JDBC驅動版本的時候,有時候會出現程序時間與數據庫時間相差很多個小時;

1.如果以北京時間為例,相差8個小時的情況一般是你在連接jdbc的url中沒有標明system_time_zone=Asia/ShangHai,一般加上參數就可以解決;

2.如果以北京時間為例,相差13小時或者14個小時,大多數情況是mysql協商會話的時候,Java把服務器的 "CST" 時區 誤以為是美國中部的 "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

在美國中部時間的CST時區里面,因為實行冬令時和夏令時,夏令時為"3月11日至11月7日 ";

在夏令時的階段,CST 為UTC-05:00, 和北京時間(UTC+08:00)相差13個小時;

在冬令時的階段,CST 為UTC-06:00, 和北京時間(UTC+08:00)相差14個小時;

 

mysql新版本的時間協商,是在JDBC和mysql建立連接的時候查詢的,在 com.mysql.cj.jdbc.ConnectionImpl 中的 initializePropsFromServer() 獲取服務器時間的時候,如果time_zone為 "SYSTEM",的時候,會取一個mysql服務器的一個時間   system_time_zone ,這個可以在mysql中查到: show variables like '%time_zone%'; 

 

如果得到的是 CST ,Java程序里面就不能判斷這是中國標准時間 CST +0800 ,會誤以為這是美國中部標准時間 CST -0500,所以在轉換相關時間格式的參數(如 timestamp Datetime 等等)時,會出錯.

 
之前我們說我們用   Asia/Shanghai 時區,也就是UTC +08:00 ,即CST +0800,即說白了,我們服務器上現在是CST+0800 的時區 ,java程序誤以為是CST-0500 的時區,所以導致時間相差13個小時,如果是冬令時,可能還會相差14個小時;
 
我們在使用 PreparedStatement 的參數填充時,如果你的時間字段就會出現此種情況,Timestamp的long類型數據會在  com.mysql.cj.jdbc.PreparedStatement.setTimestamp() 被加上時區做一次處理,所以到時和DateTime一樣的問題;
 
解決方案:
  1.在mysql的配置文件中加入  default-time-zone = '+08:00' 

  2.登入服務器數據庫,手動指定時區:

   set global time_zone = '+08:00'; 

   set time_zone = '+08:00'; 

  3.選擇任何一種方案之后,重啟數據庫;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM