一、问题情景
现在使用的mysql数据库,分别在本地和服务器上有两种配置:
本地
show variables like "%time_zone%";
select now();
服务器
show variables like "%time_zone%";
select now();
可见在数据库上都能正确获取时间。
测试代码
/**
* 数据库连接参数
* jdbc:mysql://localhost:3306/db_orm?
* useSSL=false&serverTimezone=UTC&characterEncoding=utf-8
*/
public class SqlDemo {
public static void dataTimeTest() throws SQLException {
Connection connection=DbUtil.getConnection();
PreparedStatement ps=connection.prepareStatement(
"insert into t_time(id,time) values(2,?)"
);
Date date=new Date();
System.out.println(date);
ps.setObject(1,date);
ps.executeUpdate();
}
public static void main(String[] args) throws SQLException {
dataTimeTest();
}
}
结果:
两种配置都是相同的结果,少了8个小时。
如果将连接参数改成erverTimezone=CST
少了13个小时。
二、原因分析
首先我们了解下CST时区,它是个比较混乱的时区。
CST有4种含义
- 美国中部时间 Central Standard Time (USA) UTC-06:00
- 澳大利亚中部时间 Central Standard Time (Australia)
- UTC+09:30 中国标准时 China Standard Time
- UTC+08:00 古巴标准时 Cuba Standard Time UTC-04:00
- 另外:美国从“3月11日”至“11月7日”实行夏令时,美国中部时间改为 UTC-05:00,与 UTC+08:00 相差 13 小时
当我们使用设置时区为UTC连接数据库时,mysql数据库会自动将当前时间转换成UTC时间,这里有:
Java代码中设置的时间值(当前时间)-8=数据库存储的时间值(UTC时间)
当我们使用设置时区为CTS连接数据库时,mysql数据库会自动将当前时间转换成CTS时间(美国中部夏令时时间),这里有:
Java代码中设置的时间值(当前时间)-13=数据库存储的时间值(CTS时间)
三、解决方案
时区设置成上海,即serverTimezone=Asia/Shanghai