📁系统:时间错误

type
status
date
slug
summary
tags
category
icon
password

1. 时钟工作流程

Linux 的时间同步机制较为复杂,有系统时间,硬件时间,NTP 时间等等。机器在断电重启之后,还能准确的计时,是因为在重启之后有了新的时间源来进同步,这个过程对用户来说是不透明的,所以在重启之后可能感觉不到时间进行过跳变了。
系统开机之后,从 RTC 时钟读取时间,写入系统当前时间(一般位于 /etc/init.d/xxx );当关机时,系统将当前时间保存到 RTC 时钟里,来刷新间隔。在运行的过程中,如果已经联网并且打开了 NTP 功能,则还可以使用 NTP 进行网络时间校准。
notion image

2. 时间的种类

2.1. 系统时间

开机之后的系统时间,实际上就与 RTC 时间无关了,它依赖于内核的时钟中断来计时。

2.2. 硬件时间

硬件保存时间,常用的手段是使用 RTC 硬件的主板,主板提供纽扣电池之类的硬件进行单独供电,这样可以保证即使被切断了电源,系统开机之后的时间仍然正常。

2.3. NTP 时间

NTP——网络时间协议,它是保持计算机正确时间的老式方法。ntpd是NTP守护程序,它通过周期性地查询公共时间服务器来按需调整你的计算机时间。它是一个简单的、轻量级的协议,使用它的基本功能时设置非常容易。
systemd 通过使用 systemd-timesyncd.service 已经越俎代庖地“干了NTP的活”,它可以用作 ntpd的客户端。
如果要想要搭建 ntp 服务器,目前有几个选择:chrony, ntpd and open-ntp。
Ubuntu 官网推荐使用 chrony 来设置,参考:https://ubuntu.com/server/docs/network-ntp
如果仍然想使用 ntpd 作为服务,参考:https://wiki.archlinux.org/title/Network_Time_Protocol_daemon

3. 常见问题

3.1. 时区不对

没有设置正确的时区,比如有些双系统,在切换 Linux 后,系统时间会慢 8 小时。
比如当前使用的时间是 ‘Asia/Shanghai’,则可以使用 timedatectl 命令进行设置:

3.2. 与Windows差8小时

Windows 本地时间 = RTC 时间
Linux 本地时间 = RTC 时间 + 时区 = UTC 时间 + 时区
因此,Windows 时间要比 Linux 慢 8 小时,解决方法有两个,任选其一:

3.2.1. 设置 Linux 时间

3.2.2. 设置 Windows 时间

修改注册表,将 Windows 时间改为 UTC 时间。

3.3. 时间回退

3.3.1. 回退到 1970.01.01

大概率开机启动是,RTC 功能异常,无法从硬件读取时间,所以回退到 Linux 初始时间 1970.01.01。
UNIX 及 Linux 的时间系统是由「新纪元时间」Epoch 开始计算起,单位为秒,Epoch 则是指定为 1970 年一月一日凌晨零点零分零秒,格林威治时间。

3.3.2. 回退到 BIOS 初始时间

可能是由于主板电池没电或者供电异常,保存不了之前的时间,导致每次开机会把时间复位。

3.4. 发生偏差

3.4.1. 内核修改法

从代码层面修改偏差(offset)值。X86架构主要函数在 do_fast_gettimeoffset 中。

3.4.2. 系统修改法

使用一个名为 adjtimex 的工具,可以查看当前系统时间与硬件时间的偏差值。
此时会给出对当前系统出现偏差的修正建议值,去出现数据的平均值来进行校准。如果某一个数值出现多次,较为频繁,可以选择这个数字作为校准值。这一过程可以反复进行,直至偏差越来越小。
假设此处建议值为 9800。
创建一个 systemd 服务,开机自启动。
将两个文件安装到系统中即可。

3.4.3. 误差参考

参数
增加单位数
1 天影响
tick
+1
+8.84s
ppm
+1
+0.0864s
freq
+1
+0.000001318359375s

4. 参考

中年码农的困境log-001-我与计算机