Java程序写入到Mysql数据库时间信息与真实时间相差 13或14 小时
现象
线上业务同学发现他存储到数据库侧的时间,与实际的时间相差13或14小时。
比如数据存储时,实际时间是2023-07-01 00:00:04(北京时间):
而存储到数据库中则变成了2023-06-30 11:00:04:
相差了13个小时。
有趣的现象是:我们发现数据是7月份的就差13小时,数据是2月份的则相差14个小时。
原因
因为差值很有规律,猜测是跟时区的设置有关。
mysql中时区相关的变量有system_time_zone和time_zone。
## system_time_zone
系统时区,在MySQL启动时会检查当前系统的时区并根据系统时区设置全局参数system_time_zone的值。
## time_zone
用来设置每个连接会话的时区,当值为system时,使用全局参数system_time_zone的值。
使用show variables like '%time_zone%'查看数据库的时区配置。或者通过语句查询数据时区 select @@time_zone,如果返回SYSTEM,数据库没有配置时区,使用系统时区 select @@system_time_zone。
我们看到上图中,time_zone的值是system,表示数据库没有配置时区,使用系统时区system_time_zone的值cst。
那这个CST是什么时区?
CST可以为如下4个不同的时区的缩写:
美国中部时间:Central Standard Time (USA) UTC-6:00
澳大利亚中部时间:Central Standard Time (Australia) UTC+9:30
中国标准时间:China Standard Time UTC+8:00
古巴标准时间:Cuba Standard Time UTC-4:00
那么可能就是因为cst时区的歧义,造成了问题的出现。
cst在 mysql 里被理解为 China Standard Time(utc+8),而java 的mysql jdbc驱动的代码里会设置时区,这个时区是通过TimeZone.getTimeZone("CST")获取,它返回的是美国中部时间:Central Standard Time (USA) UTC-6:00。
另外:在美国和加拿大的中部地区,"CST" 可以代表 "Central Standard Time"(中部标准时间)和 "Central Daylight Time"(中部夏令时)。这两个时区与协调世界时 (UTC) 的偏移是不同的。
Central Standard Time (CST): 中部标准时间是在非夏令时期间使用的时区,相对于协调世界时 (UTC) 向西6 小时。开始时间:每年的11月的第一个周日凌晨2点钟,结束时间:每年的3月的第二个周日凌晨2点钟。
Central Daylight Time (CDT): 中部夏令时是在夏季实施的一种时区,相对于协调世界时 (UTC) 向西 5 小时。开始时间:每年的3月的第二个周日凌晨2点钟,结束时间:每年的11月的第一个周日凌晨2点钟。
所以这也解释了为什么数据是7月份的就差13小时,数据是2月份的则相差14个小时。因为7月份是美中的夏令时是utc-5,相对于utc+8的差值,也就是13个小时,而2月份是美中的标准时间,也就是utc-6和utc+8的差值,也就是14个小时。
如何解决?
我们可以修改数据库的time_zone的值为非SYSTEM,比如+08:00;
也可以在jdbc中指明客户端使用的时区,即jdbc中加上:&serverTimezone=Asia/Shanghai
参考:https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html https://blog.csdn.net/hong10086/article/details/109037668

点个“赞 or 在看” 你最好看!

👇👇👇 谢谢各位老板啦!!!




