Mysql时间总是差8个小时
1、MySQL本身的问题
MySQL本身时间设置的就和本地时间不一致,这个很容易验证,只需要查询语句:
select now()
查出来的结果如何本地时间查了8个小时,这一般就是MySQL的时区不对,那么重新设置一下时区即可
先查看一下MySQL当前时区
show variables like '%time_zone%';
可以看到,MySQL 说它的时区是 SYSTEM,那 SYSTEM 又是啥呢?第一条说了 SYSTEM 是 UTC(协调世界时,又称世界标准时间或世界协调时间)。而我们的北京时间比 UTC 快了 8 小时,即 UTC+8。
下面进行更改即可
设置时区:
-- 修改mysql全局时区为北京时间,即我们所在的东8区
set global time_zone = '+08:00';
-- 修改当前会话时区
set time_zone = '+08:00';
-- 立即刷新生效
flush privileges;
然后再去查看MySQL时区:
show variables like '%time_zone%';
然后在SQL语句中执行now()
函数和sysdate()
函数,发现结果都是正常的
至此,MySQL本身的时区问题解决了。就是说对于直接执行SQL中使用时间函数,比如createTime和updateTime字段,插入到数据库中的时间不会出错。
2、jdbc连接的问题
读取数据时
如图,在jdbc的连接中故意设置serverTimezone=UTC
,看一下查询出来的结果为:
而数据中实际的时间为:
可以看到,查出来的数据比实际中的时间快了8个小时,为何?
由于jdbc连接地址中加入了serverTimezone=UTC
参数,这时,系统会把从数据库中查询出来的数据当做UTC时区的,而我的服务器(就是后端调用SQL的机器)的时区是GMT+8的,所以他会把查出来的时间加上8个小时。
因此,我们可以认为,在读取数据的时候,从数据库中查出来的数据会被认为是jdbc连接中的参数设置的时区的,会将这个时间转为当前机器的时区。
写入数据时
三种情况:
-
// 直接指定插入时间 String sql1 = "insert into sc_oper_log (create_time) values(?)"; jdbcTemplate.update(sql1, "2023-04-01 21:00:38");
-
// 参数使用java中的Date()对象 String sql2 = "insert into sc_oper_log (create_time) values(?)"; jdbcTemplate.update(sql2, new Date());
-
//在SQL语句使用SQL的日期函数now()或者sysdate() String sql3 = "insert into sc_oper_log (create_time) values(sysdate())"; jdbcTemplate.update(sql3);
结果是:
1:直接指定插入时间,数据库中的时间就是指定的时间
2:使用java中的Date()对象,数据库中的时间会少8个小时
3:使用SQL的日期函数,结果和MySQL的时区有关,如果MySQL时区配置正确,和本地时区一致,那么时间就是本地时间。
总之
所以说,需要在jdbc连接中指定GMT+8时区
jdbc:mysql://localhost:3306/student_growth_dt?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
参考: