关于mysql时间存储和返回时间不一致情况处理

今天在开发消息页面时碰到一个问题,在数据库中存放的时间(数据类型为datetime),到了前端展示的时候平白无故变成了晚上九点,令我很是纳闷。

image-20240222193517082

思路

观察到前端展示的时间和数据库中真实存放的时间存在八个小时的误差,而中国的时区对比世界标准时间正好相差八个小时

经过查找资料发现

DATE类型只涉及日期的存储,与时区设置无关,而serverTimezone参数是用于处理包含时间信息的日期和时间类型的时区转换。如果serverTimezone参数设置不正确,可能会导致时区转换错误,从而影响到DATETIMETIMESTAMPTIME类型值的存储和检索

举个例子,假设你的 Java 程序在一个使用 UTC 时区的服务器上运行,而你的 MySQL 数据库服务器位于使用东八区(即中国标准时间)的时区。当你在 Java 程序中创建一个 Timestamp 对象并保存到数据库时,JDBC 需要将这个时间戳从 UTC 转换为东八区的时间。同样,当从数据库读取时间戳时,也需要进行反向转换。serverTimezone=Asia/Shanghai 会告诉 JDBC 使用东八区作为转换的时区。

这也就是返回给前端的时间自动加上了八小时的原因

解决方式

将我的url链接:

1
jdbc:mysql://localhost:3306/XXX?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=false&zeroDateTimeBehavior=CONVERT_TO_NULL&allowPublicKeyRetrieval=true

修改为:

1
jdbc:mysql://192.168.1.118:3306/XXX?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true

扩展

有时在mysql中使用NOW()时会发现时间也是对不上的,没错这也是因为mysql的时区没有转变过来,那要怎么转变呢?

  1. 统一时区设置:确保MySQL数据库和应用程序(前端)使用相同的时区设置。你可以通过以下SQL命令检查MySQL的时区设置:
1
SHOW VARIABLES LIKE 'time_zone';

如果MySQL的时区设置不正确,你可以通过以下命令设置正确的时区(例如,设置为东八区):

1
SET GLOBAL time_zone = '+8:00';

请注意,这只会影响新的连接。对于现有连接,你可能需要断开并重新连接以使更改生效。

  1. 在查询时处理时区:如果你不想更改MySQL或应用程序的时区设置,你可以在查询时手动处理时区。例如,你可以使用CONVERT_TZ()函数将时间从一个时区转换为另一个时区:
1
SELECT CONVERT_TZ(your_datetime_column, 'UTC', 'Asia/Shanghai') FROM your_table;

这将把your_datetime_column中的时间从UTC转换为东八区(Asia/Shanghai)。