Java,MySQL,JDBC,Jackson时区问题

Java,MySQL,JDBC,Jackson时区问题

今天做了一个测试,主要是测试给时区参数设置不同的值,会出现什么样的问题。

  • 数据库是UTC时区。JDBC连接是GMT+8。jackson默认是UTC。JVM时区GMT+8。
    • 从数据库中查询的时间是正确的的,jackson会将时间缩短8个小时。
  • 数据库是UTC时区。JDBC连接是GMT+8。jackson是GMT+8。JVM时区GMT+8。
    • 从数据库中查询的时间是正确的的,jackson时间也是正确的。
  • 数据库是UTC时区。JDBC连接是UTC。jackson默认是UTC。JVM时区GMT+8。
    • 从数据库查询到的时间,如果是Date对象,时间会相差8个小时,在经过jackson的UTC序列化,与数据库时间一致。LocalDateTime不影响。
  • 数据库是UTC时区。JDBC连接是UTC。jackson默认是GMT+8。JVM时区GMT+8。
    • 从数据库查询到的时间,如果是Date对象,时间会相差8个小时。jackson的GMT+8序列化之后时间没有变化,与查询出来的时间一致。

得到的结论

在经过实际测试,再结合数据GPT的解答中,我理解时区问题应该是这样

  • JDBC中参数时区
    • 首先是GPT的回答
      • JDBC中的GMT+8是指告诉Java程序在处理日期和时间数据时,应该将数据库中的日期时间值转换为GMT+8时区。
      • 在Java程序与数据库进行交互时,日期和时间数据需要进行转换以确保正确处理。数据库服务器可能位于不同的时区,而Java程序通常运行在客户端所在的时区。
      • 因此,当Java程序从数据库中检索日期时间数据时,需要将这些数据转换为客户端所在的时区,以便正确显示和处理。同样地,当Java程序向数据库插入或更新日期时间数据时,也需要将数据转换为数据库服务器所在的时区。
      • 在JDBC中,可以通过在数据库连接字符串中指定时区参数来告诉Java程序使用GMT+8时区。例如,在MySQL数据库中,可以在连接字符串中添加serverTimezone=GMT%2B8参数来指定使用GMT+8时区。
      • 这样做可以确保Java程序在处理日期时间数据时,能够正确地将数据库中的值转换为客户端所在的时区,从而避免时区差异带来的问题。
      • 总之,JDBC中的GMT+8是用来告诉Java程序在处理日期时间数据时使用GMT+8时区,以确保正确地与数据库进行交互。
    • 我的理解
      • JDBC中的时区参数是设置给Java程序看的。告诉Java我用的是哪一个时区,你准备好根据我给你的时区做好转换工作。
      • 如果JVM时区是GMT+8,JDBC设置的时区是UTC。那么JDBC查询数据库得到时间字段之后,Java会认为你JDBC给我的日期时区是UTC的,我需要转换成我本地的GMT+8。这就会导致Java中接收到的时间字段与数据库时间字段真实的值不相同的问题。
      • 如果JVM时区是GMT+8,JDBC设置的时区是GMT+8。那么JDBC查询数据库得到时间字段之后,Java会认为你JDBC给我的日期时区是GMT+8的,我本地恰好也是GMT+8的时区,所以不会进行转换。
      • 对于插入数据,如果JVM时区是GMT+8,JDBC设置的时区是UTC。那么会将GMT+8转换成UTC时间,保存到数据库。
  • MySQL中的时区
    经过测试发现,当MySQL时区与对应的JDBC时区不同的时候,以JDBC设置的时区参数为准。如果MYSQL时区与Java时区不一致,在SQL中运行now()函数的时候,会获取到MySQL所在时区的时间。

小记

  • 最理想的情况是JVM,Jackson,MySQL数据库,JDBC都使用同一个时区。
  • 在使用MySQL客户端直接使用SQL查询表的时候,获取到的时间字段是原值,不会转换(对时间进行转换的是Java,具体是JDBC还是mybatis进行的转换操作不清楚)。
  • 使用Java插入数据的时候,如果JDBC时区和JVM时区相同,那么时间也不会转换。
  • 使用Java插入数据的时候,如果JDBC和JVM时区不同,那么时间会转换。
  • 经过测试,如果sql中的时间字段是以字符串格式传递的,那么mybatis则不会对字段进行时区的转换。如果sql中的时间字段是以Timestamp(或者其他关于时间的参数)传递的,mybatis会对字符串进行时区的转换。包括where条件后面带着的时间条件也会发生转变。
  • 无论是MySQL还是Orcale,Date和DateTime字段都不携带时区信息,所以无论MySQL客户端处于什么时区,查询到的时间都是不会经过时区转换的

posted on 2024-04-09 08:30  zhaoLei_Free  阅读(43)  评论(0编辑  收藏  举报

导航