时间插入 MySQL 数据库,结果竟然少了 8 小时!

今天生产插入数据的时候发现数据库时间不对劲,时间慢了八小时

9.png

一开始怀疑服务器上的时间不对,于是跑去检查了下服务器上时间和时区

date
date -R

发现没问题

2.png

继续排查是否是代码的问题

找到插入数据库时间代码
xxx.setCreateTime(LocalDateTime.now());

正常,本地测试没问题,本地mysql数据库时间显示正常

5.png

思考了下,既然代码和服务器时间都没问题,于是检查生产mysql数据库时区

查看mysql当前时间,当前时区
SELECT NOW();

show variables like '%time_zone%';

生产.png 生产数据库时区

time_zone说明mysql使用system的时区,system_time_zone说明system使用CST时区

1.png 本地数据库时区

发现生产数据库时区是UTC,而我本地的是CST,会不会跟这个有关系,继续进一步深挖

看了下jdbc连接的url中配置的时区参数(我用的数据库版本是mysql8.0以上的)

4.png 没错啊,&serverTimezone=GMT%2B8,是东八区啊,很奇怪

UTC代表的是全球标准时间,但是我们使用的时间是北京时区也就是东八区,领先UTC八个小时。mysql 使用了UTC方式来记录日志时间,也就是说这是个世界统一时间,存入mysql中的时间只能是UTC时间。mysql的timestamp类型数据,存储的时候会转化成UTC时间戳,读取时再从UTC转化为本地时间戳。各地的标准时间为格林威治时间(G.M.T)加上 (+) 或减去 (-) 时区中所标的小时和分钟数时差。中国是GMT+8.

根据这个信息,我的解决办法:

CTT - Asia/Shanghai,在jdbc的连接里使用&serverTimezone=CTT

最后重新启动应用

docker stop 容器ID
docker start 容器ID

6.png

ok,没问题,可以正确的插入时间

java.time.ZoneId类的帮助文档和源码定义了时区

  • EST - -05:00
  • HST - -10:00
  • MST - -07:00
  • ACT - Australia/Darwin
  • AET - Australia/Sydney
  • AGT - America/Argentina/Buenos_Aires
  • ART - Africa/Cairo
  • AST - America/Anchorage
  • BET - America/Sao_Paulo
  • BST - Asia/Dhaka
  • CAT - Africa/Harare
  • CNT - America/St_Johns
  • CST - America/Chicago
  • CTT - Asia/Shanghai
  • EAT - Africa/Addis_Ababa
  • ECT - Europe/Paris
  • IET - America/Indiana/Indianapolis
  • IST - Asia/Kolkata
  • JST - Asia/Tokyo
  • MIT - Pacific/Apia
  • NET - Asia/Yerevan
  • NST - Pacific/Auckland
  • PLT - Asia/Karachi
  • PNT - America/Phoenix
  • PRT - America/Puerto_Rico
  • PST - America/Los_Angeles
  • SST - Pacific/Guadalcanal
  • VST - Asia/Ho_Chi_Minh

---------------------------------更新2024-11-20---------------------------------

查看new Date()是否少了8小时,如果是,应该是jvm的时间少了8小时,通过以下方式解决;

第1方法不生效,第2方法成功解决:

1、查看时区文件/etc/localtime
执行 ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime命令修改时区

2、添加启动参数-Duser.timezone=GMT+08
java -jar -Duser.timezone=GMT+08 demo.jar --server.port=8080

参考:SpringBoot服务时间与linux服务器时间相差8小时

如果new Date()时间是对的,那么就有可能是数据库连接的问题,通过数据库url添加serverTimezone=GMT%2B8解决


已有 0 条评论

    感谢参与互动!