最后更新于

Java访问MySQL时间大8小时的解决方法


在Java项目中连接MySQL数据库时,经常遇到时间相差8小时的问题。这是由于时区参数配置不当导致的,本文将详细分析问题原因并提供解决方案。

🔍 问题分析

版本变化影响

驱动版本差异:

  • 早期SpringBoot版本:使用mysql-connector-java 5.1.x
  • SpringBoot 2.1.7+:默认使用mysql-connector-java 8.0.17+

根本原因

MySQL 8.0驱动变化:

  • 默认时区改为UTC(全球统一时间)
  • 北京时间为UTC+8
  • 时区处理逻辑发生变化

🧠 逻辑分析

时间转换过程

  1. 应用程序:使用东八区时间(UTC+8)
  2. MySQL驱动:将时间误认为UTC时间
  3. 数据库存储:按UTC时间存储
  4. 读取时:再次转换为本地时间(UTC+8)
  5. 结果:时间多加了8小时
实际时间: 2024-01-01 12:00:00 (UTC+8)
↓ 驱动误解为UTC时间
存储时间: 2024-01-01 12:00:00 (UTC)
↓ 读取时转换为本地时间
显示时间: 2024-01-01 20:00:00 (UTC+8)

✅ 解决方案

方法一:设置serverTimezone参数

在JDBC连接URL中添加时区参数:

# 使用Asia/Shanghai时区
jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=Asia/Shanghai&useSSL=false

# 使用GMT+8时区
jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=GMT%2B8&useSSL=false

方法二:Spring Boot配置

application.properties中配置:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

方法三:MySQL服务器配置

在MySQL配置文件my.cnf中设置:

[mysqld]
default-time-zone='+08:00'

🔧 常用时区参数

时区参数说明适用场景
Asia/Shanghai上海时区中国大陆推荐
GMT%2B8GMT+8时区URL编码格式
UTC协调世界时国际化应用
Asia/Hong_Kong香港时区香港地区

💡 最佳实践

开发建议

  1. 统一时区:项目中统一使用一个时区
  2. 显式配置:明确设置serverTimezone参数
  3. 测试验证:部署前测试时间显示是否正确
  4. 文档记录:在项目文档中记录时区配置

代码示例

@Configuration
public class DataSourceConfig {

    @Bean
    @Primary
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        return dataSource;
    }
}

📚 参考资料

💡 提示:升级MySQL驱动版本时,务必检查时区配置,避免时间显示错误影响业务逻辑。