mysql-connector-java版本对读取数据库时间的影响(转载请注明出处)

1 篇文章 0 订阅
1 篇文章 0 订阅

前言

    最近在做项目期间,出现了读取mysql Timestamp和实际时间相差14小时的问题,之前靠回退驱动版本到5来解决,但这不是长久之计,想搞清这个问题,故特此记录,不要纠结排版。

正文

    话不多说,先贴一幅对比表格:

    数据库:mysql5.7

    数据库驱动版本:5.1.47和8.0.13

 

 

从表格中可以看出,无论数据库时区为何,驱动版本6以下(使用5.1.47)是不存在任何问题的,6以上(使用8.0.13)在数据库时区为+8时区是没有问题的,所以重点关注数据库时区为UTC和CST这两种情况下的对比。

  从官方文档中可以看到mysql如何处理时间

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.) By default, the current time zone for each connection is the server's time. The time zone can be set on a per-connection basis. As long as the time zone setting remains constant, you get back the same value you store. If you store a TIMESTAMP value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored. This occurs because the same time zone was not used for conversion in both directions. The current time zone is available as the value of the time_zone system variable. For more information, see Section 5.1.12, “MySQL Server Time Zone Support”.

简而言之,mysql Timestamp存储会根据当前(数据库)时区转换为UTC时区进行存储,读取时会将UTC时区转换为当前(数据库)时区。

那么问题就显而易见了,问题出在时区转换上。

点进jar包源码可以看到,从6开始,驱动多了一个cj包。如果未在url里手动指定时区,那么会去读取数据库设置的时区,并使用它来转换时间;如果在url里指定了时区,会在读取数据库记录后使用指定的时区来转换时间。

另外,一般情况下国内公司及各大云服务厂商的服务器时区都为CST(China Standard Time),在其上安装的mysql默认时区为"SYSTEM",也就是CST(China Standard Time),但java中的CST含义不同,为美国中部时区(西6区,Center Standard Time) 。

基于上述,给出解释:

个人结论:虽然修改数据库时区为+8可以解决问题,但强烈建议不要这么做,应用层可以解决的问题不要抛给底层(外部组件)去做;不要再误解url里指定的时区是当前应用所在时区,其实它是覆盖(override)驱动转换UTC所用时区配置,不指定的话默认使用数据库时区(time_zone)转换。

 

最后,有一个思考题,为什么业界常用timestamp而不用datetime。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值