马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
服务器时区彻底搞懂:CST、UTC、GMT、RTC 与夏令时的关系
"服务器时间差了 8 小时""凌晨任务跑早了"" Docker 里日志 时间和宿主机对不上"——这些问题背后都指向同一组概念没分清:硬件时间(RTC)、系统时间(UTC)、当地时间(Local time)、时区(Timezone)和夏令时(DST)。搞清这五个,时间类故障基本能自己定位。
先把这些缩写分清
- CST:中国标准时间(China Standard Time),即 UTC+8。
- UTC:协调世界时,又称世界统一时间,以原子时秒长为基础、时刻尽量接近世界时的时间计量系统。
- GMT:格林尼治标准时间(Greenwich Mean Time),早期的天文Define标准,现在实际已与 UTC 等价使用。
- RTC:Real Time Clock,主板上的硬件时钟。
一、硬件时间(RTC)
1.1 什么是硬件时间
硬件时间也叫实时时钟(RTC),是主板上的一个独立于操作系统的设备,断电甚至关机后依然靠电池保持运行,功能就是记录当前的日期和时间。
1.2 怎么用它
大部分操作系统启动时从 RTC 读取时间并设置系统时间,同样也支持把系统时间写回 RTC。Unix 与类 Unix 系统里用 hwclock 查询和设置:
# 查询硬件时间
hwclock --show
# 把系统时间写入硬件时钟
hwclock --systohc
# 把硬件时钟读出并设置为系统时间
hwclock --hctosys
二、系统时间(UTC)
2.1 什么是系统时间
系统时间是计算机内部使用的时间,启动时从 RTC 初始化,之后由系统时钟(内核的一部分)跟踪,精度可以做到毫秒甚至纳秒级。
2.2 UTC 时间
系统时间通常以 UTC 表示。用 date 命令查询和设置:
# 查询系统时间(UTC)
date -u
# 查询本地时间(由系统时间 UTC 与时区共同决定)
date
# 设置本地时间(会自动做时区转换)
date -s "2022-01-01 00:00:00"
# 直接设置系统时间(不推荐,一般通过设置本地时间来间接设置)
date -u -s "2022-01-01 00:00:00"
建议只改本地时间,让系统自己换算,省去手工算时区的麻烦。
三、当地时间(Local time)
3.1 什么是当地时间
当地时间是系统时间经过时区转换后的时间。时区按地理位置划分,全球 24 个时区,每个时区大约对应 15 度经度。北京时间 UTC+8,伦敦时间 UTC+0,纽约则是 UTC−5(冬令时)。
3.2 怎么用
# 查询本地时间
date
四、时区(Timezone)
4.1 时区是什么
时区是为了统一时间而划分的地理区域。全球分为 24 个时区,每个约 15 度经度,各时区以 UTC 为基准,东边的时间比 UTC 晚(数值更大),西边则更早。
4.2 怎么设置时区
用 tzselect 交互式选择,然后把选中的时区链接到 /etc/localtime:
# 交互式选择时区
tzselect
# 或直接指定,常用这条
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
国内服务器直接 timedatectl set-timezone Asia/Shanghai 更省事。也可以安装 tzdata 包获得完整的 /usr/share/zoneinfo 数据。
4.3 Docker 容器里的时区
容器的默认时区取决于基础镜像。Debian、Ubuntu 这类常见基础镜像默认多是 UTC,创建时如果不显式指定,容器里的时间就按 UTC 显示。
想让容器时间与宿主机完全一致,运行容器时挂载这两个文件:
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro
| 文件 | 作用 |
/etc/timezone | 记录当前时区名,例如 America/New_York |
/etc/localtime | 当前时区对应的数据文件或软链接,提供本地化的日期时间显示 |
docker run -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro your_image
两个文件的作用不同,但都影响时间显示,缺一不可。只挂一个在处理跨时区的日期计算、夏令时调整时容易出错。
另外要理解一点:容器虽然与宿主机隔离,但共享同一个内核。容器调用 time() 这类系统调用时,时间直接来自宿主机内核,所以即使不挂 /etc/localtime,容器里取到的时刻依然是准的。问题在于时区是"逻辑时间"——日历计算、夏令时规则都存放在 /etc/timezone 和 /etc/localtime 里,程序要精确处理时区相关逻辑就必须有这两个文件。Docker 默认也不会自动挂载它们。
五、夏令时(DST)
5.1 什么是夏令时
夏令时是为了充分利用日照而在夏季调整时钟的做法:春末把时间提前一小时,秋初再延后一小时,让夜晚有更多 daylight,从而节省照明用电。
5.2 哪些地区采用
- 欧洲:多数欧洲国家从每年 3 月最后一个星期日开始、10 月最后一个星期日结束,包括英国、法国、德国、西班牙等。
- 北美:美国(亚利桑那州和夏威夷除外)、加拿大(萨斯喀彻温省等地除外)及墨西哥部分地区,从 3 月第二个星期日到 11 月第一个星期日。
- 大洋洲:澳大利亚只有南澳大利亚州、新南威尔士州、塔斯马尼亚州和维多利亚州实行,每年 10 月第一个星期日至次年 4 月第一个星期日。
不采用夏令时的地区:中国自 1991 年起不再实行;日本自 1952 年起没有;印度没有实行;亚利桑那州和夏威夷也不实行;非洲和南美洲大多数国家(除少数特定区域)同样不实行。
5.3 怎么处理夏令时
多数现代操作系统和编程语言的时间库都能自动处理夏令时。以 Python 为例,pytz 提供全球时区数据:
from datetime import datetime
import pytz
# 获取当前的 UTC 时间
now = datetime.now(pytz.utc)
# 转换为纽约时间(自动处理夏令时)
ny_time = now.astimezone(pytz.timezone('America/New_York'))
print(ny_time)
Unix / Linux 系统里只要时区设置正确,系统自身就会自动应用夏令时规则,业务程序无需额外处理。
六、排障速查清单
- 时间差整数小时 → 查时区:
timedatectl set-timezone Asia/Shanghai。
- 重启后时间不对 → 查 RTC 与系统时间同步:
hwclock --systohc,并确认 /etc/adjtime 里的 UTC 标识。
- 容器内时间偏 → 挂
/etc/localtime 与 /etc/timezone,或构建镜像时设 TZ=Asia/Shanghai 环境变量。
- 任务在错误时刻触发 → 检查 crontab 用的是本地时间还是 UTC,确认系统时区后再对表。
- 证书提前报"尚未生效" → 多半是时钟偏移,用
chronyd 或 ntpd 先对齐时间。
qidao123.com企服评测-应用市场 编辑提示 |