暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java程序写入到Mysql数据库时间信息与真实时间相差 13或14 小时

1227

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 在看” 你最好看!

喜欢,就关注我吧!

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

文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论