mysql 时区问题
1 查看mysql时区的三个命令

show variables like'%time_zone';

select NOW();

select @@global.time_zone,@@session.time_zone;

2 查看linux 服务器时区 和 服务器上docker容器内的时区

[root@ecs-51ff home]# date -R   ##服务器时区 
Sat, 03 Dec 2022 18:01:06 +0800
[root@ecs-51ff home]# docker exec -it home_stargate_1 /bin/bash    ##进入后端服务容器查看容器时区 
root@df36537ebdd2:/stargate# date -R
Sat, 03 Dec 2022 10:01:52 +0000
root@df36537ebdd2:/stargate# exit
[root@ecs-51ff home]# docker exec -it home_mysql_1 /bin/bash	##进入mysql容器查看容器时区
bash-4.4# date -R
Sat, 03 Dec 2022 10:03:42 +0000

好家伙 ,这不看不知道 , 一看吓一跳 ,我本以为容器时区会跟随宿主机时区, 没想到他们各自为战 ,容器内为+0 UTC, 宿主机为+8 CST,更没有想到买的华为云的墨西哥服务器 时区竟然是+8的CST,东八区,中国时区!
3
进入到mysql容器里登陆mysql,查看mysql的时区设置,是跟随system的,也就是说是Docker容器的UTC

mysql> show variables like'%time_zone';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | UTC    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2022-12-03 10:08:59 |
+---------------------+
1 row in set (0.00 sec)

mysql> select @@global.time_zone,@@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+
1 row in set (0.00 sec)

4,同一套代码, 部署到服务器和本机运行, 发现 从本机数据库拿的m对象的开始时间和结束时间是按照CST的时区来拿的,而服务器的是按着UTC拿的 这也验证了 上边第二、三步。

查看mysql时区 mysql查看数据库时区_服务器

查看mysql时区 mysql查看数据库时区_docker_02

说明go程序会以自身所在的系统(或者容器)的时区,为默认的时区。

所以要在代码的入口处操作time包指定你想要的时区。


时区问题思路

首先要搞清楚三个时区条件分别是哪个时区:

首先是两个环境时区:

一 服务器环境

服务器环境用date -R 即可查看时区

如果你的服务是用docker 起的 那还要进入到容器内查看 容器时区,因为这个时候服务依赖的是你的docker容器 命令一样 date -R

二 数据库环境

在数据库的宿主机上 date -R 查看时区,如果mysql服务是用docker 起的 那还要进入到容器内查看 容器时区

这两个条件弄清楚后,剩下的就是最容易忽略的,代码时区

也就是要到你的代码里看看有没有设置全局时间的时区,如果没有指定设置时区,那么这个程序依赖的是宿主机的时区,也就是服务器 或者 docker容器

一般这三个时区条件都弄清楚后 哪里出的问题 应该是 一眼明辨 🫡 了