一、时间概念
时间标准
某个时间系统的时间标准又称时间基准,是定义如何测量时间的一种规范,具体包括测量时间间隔的尺度基准和定义起始时刻的参考基准。
UTC
标准时间
标准时间是在同一时区内的不同地区,舍弃地区性的子午线定出的太阳时或地方平时,而共同采用的同步时间。
Time Zone
- https://en.wikipedia.org/wiki/Time_zone
- https://en.wikipedia.org/wiki/Tz_database
- https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
国际标准 ISO 8610
国际标准化组织的日期和时间的表示方法。
Date
- 2023-11-05
Time in UTC
- 06:50:41Z
- T065041Z
Date and time in UTC
- 2023-11-05T06:50:41Z
- 20231105T065041Z
Date and time with the offset
- 2023-11-04T23:50:41−07:00 UTC−07:00
- 2023-11-05T06:50:41+00:00 UTC+00:00
- 2023-11-05T13:50:41+07:00 UTC+07:00
Ref:
- The T is just a literal to separate the date from the time, and the Z means “zero hour offset” also known as “Zulu time” (UTC).
- UTC
- GMT
- Time in China - CST
- Time in the United States
- How to Think About Time https://errorprone.info/docs/time
二、Time in Linux
查看所在时区的日期和时间
date
date -R
设置系统所在时区
使用 /usr/share/zoneinfo 下时区文件替换系统时区文件
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
cp /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
Docker alpine 容器下设置
Docker alpine 镜像下构建的容器没有时区文件,需要使用 apk 添加 tzdata
FROM alpine:latest
RUN apk add -U tzdata
ENV TZ=Asia/Shanghai
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
三、Go time.Time 和 MySQL datetime 数据转换导致的时区混乱问题
一般需要保证下面三者所在时区一致才不会导致时间数据混乱
MySQL 服务器时区
查看
show variables like "%time_zone%";
修改服务器所在时区,MySQL 使用服务器系统时区
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
修改 MySQL 时区为固定时区,例如中国时区
临时(重启失效):
进入 mysql 所在服务器
set global time_zone = '+8:00';
set time_zone = '+8:00';
永久生效:
vim /etc/my.cnf
[mysqld]
default-time_zone = '+8:00'
重启mysql 服务
Go 服务所在服务器时区
date -R
Go 服务读写 MySQL 所设置的 dsn location
parseTime 设为 true,则驱动会把 MySQL 的 DATETIME 类型和 Go 的 time.Time 互转。
parseTime=true&loc=Local
或具体时区
parseTime=true&loc=Asia%2FShanghai
PS:多个 MySQL 服务之间不在同一个时区,那么就需要统一时区,使用例如 loc=Asia%2FShanghai,不能再使用 loc=Local。