0%

Linux 服务器时间修改实践指南

Linux 服务器时间修改实践指南

Linux 服务器出现时间不准确时,很多人的第一反应是执行:

1
date -s "2026-09-30 20:00:00"

这条命令确实能修改时间,但在生产环境里,时间管理并不只是一个 date 命令。

一台 Linux 服务器至少涉及三个相关概念:系统时间、时区和硬件时钟 RTC。除此之外,服务器通常还运行着 chronyd、ntpd 或 systemd-timesyncd 等时间同步服务。NTP 是这些软件使用的网络时间协议。如果没有理解它们之间的关系,很容易出现“时间刚改完又变回去了”“系统时间正确,重启后又错了”等问题。

本文从实际运维角度梳理 Linux 服务器修改时间、时区以及 RTC 的方法。

一、先搞清楚 Linux 中的三个时间概念

在区分系统时间、硬件时钟和时区之前,我们先理解一个经常出现在时间配置中的概念:UTC。

UTC 的中文名称是“协调世界时”,是全球统一的时间基准。

为什么需要这样一个基准?因为不同地区使用不同的本地时间。同一个时刻,在 UTC+8 地区可能是晚上 20:00,按 UTC 表示则是中午 12:00。如果两台服务器的日志都只写着“12:00”,却没有注明时区,就无法直接判断它们记录的事件是否发生在同一时刻。

有了统一的时间基准,不同地区的服务器就可以对齐时间,比较日志、记录事件;需要展示给用户时,再按照相应的时区转换成本地时间。

例如,下面两个时间表示的是同一时刻:

1
2
UTC:        2026-09-30 12:00:00
UTC+8: 2026-09-30 20:00:00

这里要分清:UTC 是时间基准,系统时钟和 RTC 是负责计时的机制,时区则决定一个时刻怎样表示为当地时间。

因此,“RTC 按 UTC 计时”和“应用显示 UTC+8 的本地时间”可以同时成立。机器内部采用统一基准,用户仍然可以看到熟悉的当地时间。

1. 系统时间 System Clock

系统时间由 Linux 内核维护,是服务器运行期间应用读取日期、时间的主要来源。

例如执行:

1
date

看到的是系统时钟对应的日期和时间,默认按当前进程使用的时区显示。这个输出已经包含了时区转换,不能因为它显示北京时间,就认为系统时钟内部也按北京时间计时。

日志时间、文件时间戳以及大多数业务程序读取的日期和时间,都与系统时钟有关。应用还可以选择自己的时区和显示格式。

Linux 手册对 System Clock 和 Hardware Clock 有明确区分:系统时钟由内核维护,而硬件时钟的主要作用,是在 Linux 没有运行时继续计时,供系统启动时初始化时间。

2. 硬件时钟 RTC

服务器主板通常还有一个独立的 Real-Time Clock,也就是 RTC,又经常被称为 Hardware Clock、BIOS Clock 或 CMOS Clock。

即使服务器关机,RTC 仍可以依靠电池等后备电源继续计时。

查看 RTC:

1
hwclock --show

例如,在本地时区为 UTC−4 的环境中,输出可能是:

1
2026-09-30 07:41:22.411003-04:00

hwclock --show 会按本地时间显示结果,即使 RTC 本身按 UTC 设置也是如此。 这里的 -04:00 是输出的时区偏移,不能据此判断 RTC 保存的是本地时间。

系统启动时,可以利用 RTC 初始化系统时间;进入 Linux 后,操作系统和应用主要使用 System Clock。

3. 时区 Time Zone

时区本身并不是另一块“时钟”。常见的时区标识包括:

1
2
3
4
UTC
Asia/Shanghai
Asia/Taipei
Europe/Berlin

它决定一个时刻如何转换成人类看到的当地日期和时间。系统时区通常作为默认值,应用也可以另外指定时区。

下面这张图描述启动时初始化系统时间,以及应用显示时间的关系:

二、不同 Linux 发行版应该使用什么命令

timedatectl 属于 systemd,并不是 Linux 内核提供的通用命令。

在提供该工具及相应服务的 systemd 系统上,本文以 timedatectl 作为主要配置入口,因为它可以统一查看和设置系统时间、时区、RTC 模式以及自动同步状态。

RHEL 官方文档给出了使用 timedatectl set-timezone 和 timedatectl set-time 管理时区和时间的方法;openEuler 官方文档同时介绍了 timedatectl、date 和 hwclock。

date 和 hwclock 在 systemd 系统上同样适用:前者用于查看、格式化和设置系统时间,后者用于操作硬件时钟。选择哪一个,取决于要完成的操作。

Alpine Linux 默认使用 OpenRC,通常没有 timedatectl,可以使用发行版提供的 setup-timezone 设置时区。

三、生产环境修改时间之前,先检查当前状态

不要拿到服务器后直接执行修改命令。在提供 timedatectl 的系统上,先执行:

1
timedatectl

典型结果:

1
2
3
4
5
6
7
Local time: Wed 2026-09-30 08:00:31 EDT
Universal time: Wed 2026-09-30 12:00:31 UTC
RTC time: Wed 2026-09-30 12:00:32
Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
字段 含义
Local time 系统时间按当前系统时区显示的结果
Universal time 系统时间按 UTC 显示的结果
RTC time RTC 的时间读数,需要结合 RTC in local TZ 理解
Time zone 当前系统时区
System clock synchronized 内核是否报告系统时钟已同步
NTP service systemd 所识别的时间同步服务是否处于活动状态
RTC in local TZ 系统是否配置为按本地时间维护和解释 RTC

使用 chrony 时,还可以通过第十节的命令检查同步状态和时间源。

对于普通 Linux 服务器,通常希望看到:

1
RTC in local TZ: no

这表示系统按 UTC 维护和解释 RTC。

接下来先判断问题属于哪一种:

  • UTC 正确,只有本地显示不符合预期:检查系统时区以及应用自己的时区配置,通常无需修改系统时钟。
  • UTC 本身错误:检查同步服务、时间源和网络,再判断是否需要手工改时。

四、生产环境手工修改时间的流程

下面以 systemd 环境为例,前提是已经确认系统时钟错误,并且确实需要手工调整。

手工改时可能使系统时间突然向前或向后跳变。

数据库、集群、日志以及认证服务都可能受到影响,执行前应评估业务影响,必要时安排维护窗口。日常校时应优先检查和修复自动同步。

第一步:确认时区

查看可用时区:

1
timedatectl list-timezones

如果只想查亚洲:

1
timedatectl list-timezones | grep '^Asia/'

需要使用中国标准时间时,可以设置为:

1
sudo timedatectl set-timezone Asia/Shanghai

如果服务器按运维规范使用 UTC,则保留 UTC,不必为了手工改时统一切换到上海时区。

systemd 会将 /etc/localtime 链接到对应的时区数据文件。目标文件采用二进制 TZif 格式,用 cat 查看出现不可读字符是正常的。

管理员输入的时间如果没有注明时区,通常会按本地时间解释。因此,先确认时区,可以避免把同一个时间字符串理解成不同的时刻。

如果问题仅仅是时区错误,修改并验证显示结果后即可结束,无需继续修改系统时钟。

第二步:检查并关闭自动时间同步

在 systemd 能识别对应同步服务的环境中,可以执行:

1
sudo timedatectl set-ntp false

这条命令会停止并禁用 systemd 所识别的网络时间同步服务,并不是仅暂停当前这一次同步。

如果已识别的同步服务仍在运行,timedatectl set-time 会拒绝修改。不同版本的报错文字可能不同,例如:

1
Failed to set time: NTP unit is active

openEuler 官方文档也在 timedatectl 的使用说明中要求,手工修改日期或时间前先关闭 NTP 自动同步。这个限制不能直接套用到 date -s:后者可能修改成功,但时间随后仍可能被同步服务重新校准。

执行后再次检查:

1
timedatectl

确认已识别的同步服务不再活动:

1
NTP service: inactive

如果存在自定义同步服务,应另外确认其状态。在虚拟机中,还应检查 VMware Tools、Hyper-V 等宿主机时间同步机制;关闭 NTP 不等于关闭所有能够调整 Guest OS 时间的机制。

第三步:修改系统时间

1
sudo timedatectl set-time "2026-09-30 20:00:00"

时间字符串使用 YYYY-MM-DD HH:MM:SS 格式。这里假设已经设置为 Asia/Shanghai,并且示例中的日期和时间已替换为实际需要设置的值。

timedatectl set-time 在修改 System Clock 的同时,也会更新 RTC。 因此,在 RTC 更新成功的情况下,通常不需要再执行一次 hwclock --systohc。

date 同样可以修改系统时间,但 date -s 本身不负责更新 RTC,也不会停止或禁用时间同步服务。下面单独介绍这种方式。

五、使用 date -s 时如何处理 RTC

使用传统命令前,同样需要确认时区,并处理好正在运行的自动校时服务。没有 systemd,不代表没有自动时间同步。

修改系统时间:

1
sudo date -s "2026-09-30 20:00:00"

如果已确认系统时间正确,并且需要立即写入 RTC,可以执行:

1
sudo hwclock --systohc

--systohc 即 sys-to-hc,方向是 System Clock → Hardware Clock。

date -s 本身不写 RTC,但系统中可能另有 RTC 自动同步机制,例如 chrony 的 rtcsync 配合内核周期性写入。因此,不应把 hwclock --systohc 理解为执行 date -s 后任何环境都必须追加的命令。

六、RTC 建议使用 UTC

前面已经介绍过,RTC 可以按 UTC 或本地时间计时。systemd 官方建议尽可能使用 UTC,避免因时区变化或夏令时切换产生问题。

因此,普通 Linux 服务器通常保持 RTC in local TZ: no 即可;如果已经是这个状态,就无需修改。

七、不要把 --systohc 和 --hctosys 搞反

命令 同步方向
hwclock --systohc System Clock → RTC
hwclock --hctosys RTC → System Clock

util-linux 手册提醒,不应在已经运行的系统上使用 --hctosys,因为系统时间突然跳变可能破坏文件系统时间戳。它主要用于启动阶段初始化时间。

发现系统时间和 RTC 不一致时,应先确认哪个时间正确,避免直接用 RTC 覆盖系统时间。

八、修改完成后如何验证并恢复同步

1. 验证时间和时区

依次检查:

1
2
3
timedatectl
date
sudo hwclock --show

没有 timedatectl 的环境,使用后两条命令,并结合发行版的时区配置和实际同步服务检查。

在 Asia/Shanghai 时区、RTC 按 UTC 设置且时间正确的情况下,timedatectl 中相关字段的关系如下。为便于比较,这里省略了命令执行间隔造成的秒数差异:

1
2
3
4
5
Local time:       2026-09-30 20:00:00 CST
Universal time: 2026-09-30 12:00:00 UTC
RTC time: 2026-09-30 12:00:00
Time zone: Asia/Shanghai (CST, +0800)
RTC in local TZ: no

这里 RTC time 比本地时间少 8 小时是正常的。RTC 按 UTC 计时,而上海时区的偏移为 +08:00。

同一时刻,hwclock --show 则可能显示:

1
2026-09-30 20:00:00.000000+08:00

两种输出并不矛盾:hwclock 将读取到的 RTC 时间换算成本地时间显示。

2. 按原有策略恢复自动同步

如果服务器原本需要自动同步,应在确认时间源可靠、配置和网络正常后,恢复原有同步服务。

对于由 timedatectl 管理、且其选择的同步服务符合预期的环境,可以执行:

1
2
sudo timedatectl set-ntp true
timedatectl

set-ntp true 会启用并启动已知列表中第一个存在的同步服务;安装了多个实现时,应确认启动的是原计划使用的那个,不能假定它必然恢复先前的服务组合。

chrony 环境还应检查:

1
2
chronyc tracking
chronyc sources -v

服务启动后可能需要一段时间才能完成同步,不应只看到 NTP service: active 就结束验证。

如果属于离线或明确采用手工校时的环境,可以保持自动同步关闭,但应记录原因和后续维护方式。若之前是时间源错误导致时间异常,应先修复时间源,再恢复同步。

九、两套手工改时命令速查

以下仅供已确认需要手工改时的场景使用。示例采用 Asia/Shanghai,请按实际环境调整;修改完成后按第八节验证并恢复原有同步策略。

systemd 环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看当前状态
timedatectl

# 关闭已识别的自动同步服务
sudo timedatectl set-ntp false

# 按实际需要设置时区
sudo timedatectl set-timezone Asia/Shanghai

# 将示例替换为已核实的实际时间;此操作同时更新 RTC
sudo timedatectl set-time "2026-09-30 20:00:00"

# 验证结果
timedatectl
sudo hwclock --show

# 确认时间源正常且应恢复自动同步时,再执行:
# sudo timedatectl set-ntp true

传统命令方式

前提是已用发行版相应工具确认时区,并停止或协调好实际运行的同步服务。

1
2
3
4
5
6
7
8
9
10
11
# 将示例替换为已核实的实际时间
sudo date -s "2026-09-30 20:00:00"

# 需要立即将正确的系统时间写入 RTC 时执行
sudo hwclock --systohc

# 验证结果
date
sudo hwclock --show

# 完成后按原有策略恢复同步服务,并检查是否同步成功

不同发行版的服务名称和管理方式不完全相同,这里不提供一条通用的传统服务启停命令。

十、生产服务器不应长期依赖手工校时

前面的方法解决的是“管理员确实需要手工修改时间”的问题。日常运行应让系统通过可靠的时间源持续校准,并监控同步状态和误差。

自动同步也不等于系统时间绝不会跳变。chrony 通常通过加快或减慢时钟逐渐校正偏差,但在满足 makestep 等配置条件时,也可能直接调整时间。对时间敏感的业务,需要一并关注校时策略。

RHEL 8 使用 chronyd 实现 NTP 时间同步;SUSE Linux Enterprise Server 15 将 chrony 作为默认 NTP 实现。Ubuntu 25.10 的默认安装也改用 chrony,替代 systemd-timesyncd

升级过来的机器、定制镜像以及手动调整过的软件环境,应检查实际运行的服务,不能只按发行版名称或版本推断。

在 chrony 环境中,timedatectl 仍可用于查看基本状态和设置时区;chrony 的具体同步状态、时间源和运行参数,则使用 chronyc 查看和管理。

查看本机同步状态:

1
chronyc tracking

查看时间源及其选择状态:

1
chronyc sources -v

理解这一点以后,Linux 时间管理也就不再只是记住几个命令。

真正需要掌握的是三者之间的关系:

现代 Linux 服务器真正应该保证的,不是“管理员会不会修改时间”,而是系统能够通过可靠的时间源长期维持准确、连续并且一致的时间。