最可靠方式是用 timedatectl 设置时区:先timedatectl status查看,再timedatectl list-timezones筛选,最后sudo timedatectl set-timezone asia/shanghai设置;手动改/etc/localtime易导致服务时间解析错误。

Linux 设置时区最可靠的方式就是用 timedatectl,别碰 /etc/localtime 软链接或 tzselect 手动改,容易错且不被 systemd 服务识别。
怎么用 timedatectl 查看和设置时区
先确认当前状态:timedatectl status 会显示 Time zone: 行,比如 Asia/Shanghai (CST, +0800)。注意括号里是缩写和偏移,不是时区名本身。
列出所有可用时区:timedatectl list-timezones,结果很长,建议管道过滤:timedatectl list-timezones | grep -i shanghai。
设置时区必须用完整区域/城市名(不能只写 CST 或 +0800):
sudo timedatectl set-timezone Asia/Shanghaisudo timedatectl set-timezone America/New_York- 错误示例:
sudo timedatectl set-timezone CST→ 报错Unknown time zone 'CST'
为什么不能直接 ln -sf /usr/share/zoneinfo/... /etc/localtime
老教程常教手动软链,但 systemd 系统下这会导致 timedatectl 显示混乱,甚至部分服务(如 rsyslog、journalctl)日志时间仍按 UTC 解析。
timedatectl set-timezone 不仅更新 /etc/localtime,还会写入 /var/lib/systemd/clock 并通知所有监听时间变化的 unit,这是手动操作做不到的。
常见坑:
- 软链指向了
/usr/share/zoneinfo/ROC(中华民国标准时间)→ 实际是 UTC+08:00,但名字和语义不符,timedatectl无法识别为合法时区 - 软链指向了
/usr/share/zoneinfo/Asia/Chongqing→ 虽然时间相同,但 systemd 不推荐非标准城市名,list-timezones里根本不会列出来
timedatectl 和系统时间同步的关系
时区设置和 NTP 时间同步是两件事,但容易混淆。设对时区后,如果系统时间本身不准,date 命令还是显示错——因为时区只是“解释”时间,不负责“校准”时间。
检查 NTP 是否启用:timedatectl status 看 NTP enabled: 和 NTP synchronized: 两行。
启用自动同步(推荐):
-
sudo timedatectl set-ntp true→ 启用 systemd-timesyncd - 如果用
chrony或ntpd,要确保对应服务运行,timedatectl只管协调,不管具体实现 - 禁用 NTP 后再设时区,
date显示可能立刻跳变(比如从 UTC 切到 CST,秒数不变但显示加了 8 小时)
真正麻烦的是容器或 chroot 环境:宿主机设了时区,容器内默认还是 UTC,得单独挂载 /etc/localtime 或在启动时传 TZ 环境变量——这点很容易漏,而且不同容器运行时行为还不一致。










