服务器时间不准是个隐蔽但要命的问题:日志对不上、证书校验失败、数据库主从复制出错、cron 任务差 8 小时。date 看时间、timedatectl 管时区和 NTP、chrony 做网络对时,这三件事合起来就是 Linux 时间管理的全貌。这一篇从手动设时间到自动对时一次讲完。
一、date:看时间和格式化
语法格式
bash
date [选项] [+格式]
常用格式符
| 符号 | 含义 |
|---|---|
%Y |
四位年 |
%m |
月 01-12 |
%d |
日 01-31 |
%H |
小时 00-23 |
%M |
分 00-59 |
%S |
秒 00-60 |
%s |
Unix 时间戳(从 1970-01-01 起的秒数) |
%F |
等于 %Y-%m-%d |
%T |
等于 %H:%M:%S |
示例与预期输出
不带参数直接看当前时间:
bash
date
预期输出:
text
Wed Sep 16 10:30:45 CST 2026
格式化成自己要的样子:
bash
date +"%Y-%m-%d %H:%M:%S"
预期输出:
text
2026-09-16 10:30:45
算时间差或看相对时间:
bash
date -d "3 days ago"
预期输出:
text
Sun Sep 13 10:30:45 CST 2026
-d 后跟自然语言,写脚本里算日志保留天数、定时清理很顺手。
手动设时间(没跑 NTP 的场景才需要):
bash
sudo date -s "2026-09-16 10:31:00"
现代服务器都跑 NTP,手动设完过一会儿就被 chrony 拉回标准时间。
二、timedatectl:时区与 NTP 开关
timedatectl 是 systemd 提供的时间管理工具,一条命令看完时间、时区、NTP 状态。
语法格式
bash
timedatectl [命令]
常用子命令
| 命令 | 作用 |
|---|---|
timedatectl |
看完整状态 |
timedatectl list-timezones |
列出所有时区 |
sudo timedatectl set-timezone 时区 |
设时区 |
sudo timedatectl set-time "时间" |
手动设时间 |
sudo timedatectl set-ntp true |
开关 NTP 自动对时 |
示例与预期输出
看状态:
bash
timedatectl
预期输出:
text
Local time: Wed 2026-09-16 10:30:45 CST
Universal time: Wed 2026-09-16 02:30:45 UTC
RTC time: Wed 2026-09-16 02:30:46
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
重点看四行:当前时区、是否已同步、NTP 服务活没活、硬件时钟走 UTC 还是本地时间。
改时区。先找时区名:
bash
timedatectl list-timezones | grep -i shanghai
预期输出:
text
Asia/Shanghai
设上:
bash
sudo timedatectl set-timezone Asia/Shanghai
它本质是把 /etc/localtime 软链到 /usr/share/zoneinfo/Asia/Shanghai。手动改也行,timedatectl 省事。
NTP 开关:
bash
sudo timedatectl set-ntp true
开了之后 systemd 会拉起 chrony 或 systemd-timesyncd,不用自己再 enable。
三、系统时钟与硬件时钟
机器上其实有两个钟:
- 系统时钟:Linux 内核维护的软件时间,开机时从硬件时钟读一次,之后自己走。
- 硬件时钟(RTC):主板上靠电池供电的时钟,关机也在走。
看硬件时钟:
bash
sudo hwclock
预期输出:
text
2026-09-16 10:30:50.123456+08:00
把系统时间写回硬件:
bash
sudo hwclock --systohc
把硬件时间读进系统:
bash
sudo hwclock --hctosys
通用建议:硬件时钟统一走 UTC,由操作系统换算成本地时区。timedatectl 输出里 RTC in local TZ: no 就是这个状态。Windows 双系统机器如果 Windows 把 RTC 当本地时间用,两边会互相打架,这时候才需要 timedatectl set-local-rtc 1,纯 Linux 服务器别动这个。
四、chrony:NTP 对时的现代选择
Ubuntu 22.04 之后、Rocky 8/9 默认都带 chrony。它由两个部分组成:chronyd 后台服务、chronyc 交互工具。
安装与启动
bash
sudo apt install chrony # Ubuntu/Debian
sudo dnf install chrony # CentOS/Rocky
sudo systemctl enable --now chronyd
配置文件
| 发行版 | 配置路径 |
|---|---|
| Ubuntu/Debian | /etc/chrony/chrony.conf |
| CentOS/Rocky | /etc/chrony.conf |
默认内容几行关键的:
text
pool ntp.ubuntu.com iburst maxsources 4
pool ntp.aliyun.com iburst maxsources 2
driftfile /var/lib/chrony/chrony.drift
makestep 1.0 3
pool/server:NTP 服务器地址,pool是一组地址,server是单点。iburst让启动时快速连发几个请求。driftfile:记录本机时钟的快慢漂移,下次启动参考。makestep 1.0 3:前三次同步时如果偏差超过 1 秒就直接跳,不等慢慢追上。
国内机器把默认国外 pool 换成国内的更稳:
text
server ntp.aliyun.com iburst
server cn.ntp.org.cn iburst
改完重启:
bash
sudo systemctl restart chronyd
查看同步状态
bash
chronyc tracking
预期输出(节选):
text
Reference ID : CB699D03 (203.107.6.88)
Stratum : 3
Ref time (UTC) : Wed Sep 16 02:31:10 2026
System time : 0.000023456 seconds fast of NTP time
Last offset : -0.000012345 seconds
RMS offset : 0.000034567 seconds
Leap status : Normal
Leap status : Normal 是健康状态。System time 那行告诉你本机时间相对 NTP 快了还是慢了多少。
看正在用哪些上游服务器:
bash
chronyc sources
预期输出:
text
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^+ ntp.aliyun.com 2 6 377 45 +123us[-123us] +/- 45ms
^* 203.107.6.88 2 6 377 12 +23us[ +23us] +/- 31ms
^- cn.ntp.org.cn 2 6 377 30 -89us[ -89us] +/- 58ms
^* 前面带星号的那行就是当前实际在用的源。^+ 是备选,^- 是被淘汰的。Reach 全 377 表示连续八次都连上了。
chronyc 不只是看,还能临时管:
| 命令 | 作用 |
|---|---|
chronyc sources -v |
看源的详细质量指标 |
chronyc makestep |
立刻按当前测量值跳一次,不等慢慢收敛 |
chronyc offline / chronyc online |
手动标记网络断/通,影响选源 |
chronyc waitsync 10 |
阻塞等待最多 10 秒直到同步完成,脚本里用 |
刚开机时间差得离谱、又不想等 chrony 慢慢追的时候,sudo chronyc makestep 一把拉齐,比手动 date -s 准------它是按 NTP 源测量值跳的,不是瞎设。
五、⚠️ 常见错误
- 时区改了但 cron 还是按旧时间跑:改时区要重启依赖时间的服务,或者干脆重启机器。systemd 的服务大多读一次时区,不主动刷新。
- chrony 装了但不同步 :
timedatectl里NTP service: inactive。多半是装了 chrony 但 systemd-timesyncd 还占着,两个 NTP 客户端抢同一个 socket。sudo systemctl disable --now systemd-timesyncd留一个。 - 容器里时间不准:容器共享宿主机内核时间,自己跑 chrony 没用。把宿主机时间搞对,容器自然对。
- RTC 在 local TZ 导致跨天跳变 :纯 Linux 机器确认
RTC in local TZ: no,双 Windows 才需要打开。 - 服务器在没外网的内网 :找一台能联网的机器当内网 NTP 服务器,其他机器
server 那台内网IP iburst指过去,别让所有机器直接打公网。
六、知识扩展:chrony 和 ntpd 到底差在哪
老文档里常见 ntpd,现在新机器基本都换成 chronyd。两者都讲 NTP 协议,但设计取向不一样。
| 对比项 | ntpd | chronyd |
|---|---|---|
| 首次同步速度 | 慢,要慢慢调 | 快,几分钟内收敛 |
| 离线/间歇网络 | 表现差 | 能记录漂移,联网后快速修正 |
| 资源占用 | 较高 | 轻 |
| 虚拟机友好 | 一般 | 好,VM 时钟漂移大它处理得好 |
| 配置文件 | /etc/ntp.conf |
/etc/chrony.conf 或 /etc/chrony/chrony.conf |
| 查询工具 | ntpq -p |
chronyc sources |
选谁?Ubuntu 22.04+/Debian 12+、Rocky 8+/CentOS 9+ 默认都是 chrony,没必要倒回去装 ntpd。老 CentOS 7 上默认是 ntpd,升级时记得迁移。
NTP 协议本身是分层的,叫 stratum:
text
stratum 1: 直接接原子钟/GPS 的服务器
stratum 2: 从 stratum 1 同步
stratum 3: 从 stratum 2 同步(你我服务器多半在这层)
...以此类推
chronyc tracking 输出里那个 Stratum : 3 就是这个意思。stratum 数字越小越准,家庭和办公网络用公网 pool 拿到 stratum 2/3 的源完全够,没必要自己架 GPS 时钟。