Spring连接Mysql获取数据时间快8小时或慢8小时时区问题

344 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

直接放结论,有用的话点个赞

结论:

按如下方法设置

spring:
  application:
    name: serviceName
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/databaseName?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

问题描述:

后台微服务用feign从另一微服务中获取了带有date属性的实体类,但是从数据库中取出快8小时 在这里插入图片描述

在这里插入图片描述

此时application.yml设置是 在这里插入图片描述 数据库是 在这里插入图片描述


原因分析:

快8小时原理

经过我严密的逻辑理解,serverTimezone是告诉spring你即将连接的数据库是哪个时区的,spring本身时区:在哪个时区运行就是哪个时区

倘若我在中国运行,serverTimezone=UTC,意思就是获取0时区的数据回到中国,所以要+8小时

慢8小时原理

serverTimezone=Asia/Shanghai,这样设置,虽然从数据库中获取的时间正常无偏差,但是到了页面展示时就慢8小时,因为对象在微服务之间传输时被转换成了Json格式,而json默认时区是0时区,所以-8小时

在application.yml中,可以设置俩处属性 jackson的time-zone 和 url的serverTimezone

spring:
  application:
    name: personnel
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://127.0.0.1:3306/health_personnel?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    url: jdbc:mysql://127.0.0.1:3306/health_personnel?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: root
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

其中: serverTimezone 影响客户端写入数据, 设置成UTC写入东8时区的mysql,会-8小时 设置成Asia/Shanghai写入东8时区的mysql,正常

time-zone 影响客户端间传输pojo类的date类型属性,因为要转换成json, 不设置会慢8小时 在这里插入图片描述 在这里插入图片描述

不用管mysql的time_zone,这俩种设置获取时间的效果一样: SET GLOBAL time_zone = 'SYSTEM'; SET GLOBAL time_zone = '+08:00';


解决方案:

测试结果如下 时间转换

项目显示效果
UTC + 不设置time-zone微服务查出的数据比数据库快8小时,页面展示和数据库一致
Asia/Shanghai + 不设置time-zone微服务查出的数据和数据库一样,页面展示比数据库慢8小时
Asia/Shanghai + 设置time-zone微服务查出的数据和数据库一样,页面展示和数据库一致