导读:计算机系统的时间,对于双系统用户,有时会遇到系统时间总是不对,每次重启进入另外一个系统都要手动调整同步。或许需要阅读下文了解个大概。
若不想浪费时间,简单的说,硬件时钟和所有操作系统的系统时钟的时间标准都设置为UTC全球时间标准即可。只要你知道怎么设置,就可以避免系统时间异常的问题,也不用继续看下文了。

1. 计算机系统时间的组成

在操作系统中,时间(时钟)time (clock) 由四部分决定:

  1. 时间数值 time value ;
  2. 时间标准:
    1. local time本地时间,
    2. Coordinated Universal Time (UTC)通用协调时间,也叫 全球时间标准 ,与时区值无关。也称为GMT(Greenwich Mean Time格林威治标准时间)
  3. 时区time zone ; 比如:Asia/Shanghai (CST, +0800)
    • 几个相同简写的CST https://zh.wikipedia.org/wiki/CST
      • CST 中国 China Standard Time 比世界协调时快八小时(: UTC+8)
      • CST Central Standard Time 北美部分地区使用(: UTC-6)
      • CST 古巴 Cuba Standard Time (: UTC-5)
  1. 夏令时DST(Daylight Saving Time)(如果适用,中国已经废止(1986-1992))

2. 计算机系统时钟

计算机主机系统始终有硬件时钟和系统时钟,网络上还有提供时钟同步的NTP时间服务器。

  • Hardware clock 硬件时钟: 计算机硬件有个使用电池的实时时钟(Real-time Clock, RTC)也叫(CMOS时钟,BIOS时间)。使用的时间标准由操作系统设置。(建议使用UTC全球时间标准)
  • Software clock 软件时钟: 计算机系统运行时的时钟(Syetem clock)。

NTP 网络时间协议(Network Time Protocol)是用于通过分组交换,可变延迟数据网络同步计算机系统的时钟的协议。实现时间同步.

3. 计算机系统时钟运行的行为

大多数计算机系统的标准行为是:

  1. 关机状态:硬件时钟有电池供电,始终在主板上默默运行着。
  2. 通电进入BIOS: 主板BIOS系统界面能够看到并设置硬件时间。
  3. 电脑开机:
    1. 开机引导时:使用硬件时钟设置系统时钟。Arch Linux系统开机时间会更新到/etc/adjtime
    2. 系统运行时:系统正常运行后,由系统内核独自运行系统时钟。
    3. 时钟同步服务:需要联网,大部分操作系统都带有联网后能够和网络上的NTP服务器同步系统时钟,修正系统时间的准确性。
    4. 系统关机时:会使用系统时钟设置硬件时钟,更新硬件时钟。

4. 计算机时钟查看与维护

4.1 硬件时钟

硬件时钟(又名实时时钟(RTC)或CMOS时钟)存储的值:年,月,日,小时,分钟和秒。
仅2016年或更高版本,UEFI固件能够存储时区,以及是否使用DST。

读硬件时钟
$ sudo hwclock
2019-04-25 21:25:40.858698+08:00

查看开机引导时更新的系统时刻
$ cat /etc/adjtime
  0.000000 1553241994 0.000000
  1553241994
  UTC
额,这里的“1553241994”就是最近一次开机引导的时刻了(秒数)。
是自1970年1月1日午夜UTC以来,到开机引导时,硬件时钟的时间之间的秒数。

将硬件时钟设置为当前系统时钟:此外,/etc/adjtime如果不存在,它会更新或创建它。
# hwclock --systohc

4.2 系统时钟

系统时钟(又名软件时钟)跟踪:时间,时区和夏令时(如果适用)。它由Linux内核计算为自1970年1月1日午夜UTC以来的秒数。系统时钟的初始值由硬件时钟计算,具体取决于内容/etc/adjtime。启动完成后,系统时钟独立于硬件时钟运行。Linux内核通过计算定时器中断来跟踪系统时钟。

4.2.1 读取时钟

要检查当前系统时钟时间(以本地时间和UTC显示)以及RTC(硬件时钟):
$ timedatectl

  • Local time: Fri 2019-04-26 16:29:01 CST // 本地时间
  • Universal time: Fri 2019-04-26 08:29:01 UTC // 全球时间
  • RTC time: Fri 2019-04-26 08:29:04 // 硬件时间
  • Time zone: Asia/Shanghai (CST, +0800) // 时区
  • System clock synchronized: no // 系统时间同步: 无
  • NTP service: inactive // NTP网络同步服务: 未激活
  • RTC in local TZ: no // 硬件时钟时间标准: 不是本地时间,

*有趣的事情就发生了,Local time是当前的系统时间;RTC time是当前的硬件时间;
开机引导时,系统时间获取硬件时间作为自己的时间,2个时钟独自运行了一段时间后,出现了差异。
再如Unix等服务器系统开机后会连续运行数月,甚至数年。出现的差异可能会更加明显。

$ who -b //查看最近一次开机时刻;
system boot 2019-04-23 11:44
$ uptime // 查看连续运行时间;
16:22:59 up 3 days, 4:38, 1 user, load average: 2.67, 2.16, 1.86
$ cat /proc/uptime // 连续运行秒数;
275958.56 379537.26
// 其他命令也能看到: w, top, last reboot,
*由此可以了解到,本机连续运行了3天多,系统时钟就比硬件时钟慢了3秒。

4.2.2 设置系统时钟

直接设置系统时钟的本地时间:
# timedatectl set-time "yyyy-MM-dd hh:mm:ss"
# timedatectl set-time "2019-04-26 11:13:54"

4.2.3 双系统的时间标准设置

第一章有讲到两种时间标准:本地时间和协调世界时(UTC)。
本地时间标准取决于当前时区,而UTC是全球时间标准,与时区值无关。
或者说,本地时间=UTC+时区
默认情况下,Windows使用localtime,macOS使用UTC,类UNIX系统也有所不同。
使用UTC标准的操作系统通常会将硬件时钟视为UTC,并根据时区对其进行调整以设置启动时的操作系统时间。

如果计算机上安装了多个操作系统,它们将从相同的硬件时钟获取当前时间:建议采用硬件时钟的唯一标准,以避免系统间冲突并将其设置为UTC。
否则,如果硬件时钟设置为本地时间,则例如在DST改变之后,多个操作系统可以调整它,从而导致过度校正; 当在不同时区之间旅行并使用其中一个操作系统重置系统/硬件时钟时,也可能出现问题。

要将硬件时钟时间标准更改为本地时间,请使用(不推荐):
#timedatectl set-local-rtc 1
要恢复为UTC的硬件时钟,请键入:
#timedatectl set-local-rtc 0
这些会/etc/adjtime自动生成并相应地更新RTC; 无需进一步配置。

注意:使用timedatectl需要有源dbus。因此,可能无法在chroot下使用此命令(例如在安装期间)。在这些情况下,您可以恢复为hwclock命令。如果/etc/adjtime不存在,则systemd假定硬件时钟设置为UTC。

4.2.4 Windows中的UTC

要使用Windows进行双重启动,建议将Windows配置为使用UTC,而不是使用Linux来使用本地时间。(Windows默认使用localtime:请参阅此内容。)

它可以通过一个简单的注册表修复来完成:打开regedit并添加DWORD了价值32位的Windows,或QWORD为64位之一,十六进制值1到注册表:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

您可以从运行的管理员命令提示符执行此操作:
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f
(替换DWORDQWORD64Windows。)(Replace DWORD with QWORD for 64-bit Windows.)

或者,使用以下内容创建一个文件*.reg(在桌面上),然后双击它以将其导入注册表:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"=dword:00000001
(替换dwordqword64Windows。)(Replace dword with qword for 64-bit Windows.)

如果Windows因DST(夏令时)更改而要求更新时钟,请放行。它将按预期将UTC保留为UTC,仅校正显示的时间。
如果您遇到时间偏移问题,请尝试重新安装tzdata,然后重新设置时区:
# timedatectl set-timezone America/Los_Angeles

4.2.5 时区

要检查为系统定义的当前区域:
$ timedatectl status

列出可用区域:
$ timedatectl list-timezones

设置时区:
# timedatectl set-timezone Zone/SubZone
# timedatectl set-timezone Canada/Eastern

这将创建一个/etc/localtime指向zoneinfo文件的符号链接/usr/share/zoneinfo/。
$ ls /etc/localtime
/etc/localtime@
$ ls /etc/localtime -l
lrwxrwxrwx 1 root root 33 Mar 22 16:05 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai

如果您选择手动创建链接(例如在chroot中timedatectl无法工作),请记住它必须是符号链接,如archlinux(7)中所指定:
# ln -sf /usr/share/zoneinfo/Zone/SubZone /etc/localtime

提示:也可以使用tzselect以交互方式选择时区。$ tzselect

4.2.6 时间偏差

每个时钟的值都与实时不同(最佳表示为国际原子时); 没有时钟是完美的。基于石英的电子时钟可以保持不完美的时间,但保持一致的不准确性。这个基础'不准确'被称为'时间偏差'或'时间漂移'。

设置硬件时钟时hwclock,每天以秒为单位计算新的漂移值。通过使用新值集和恰好在集合之前的硬件时钟值之间的差来计算漂移值,同时考虑先前漂移值的值和硬件时钟的最后设置时间。新的漂移值和设置时钟的时间被写入文件,/etc/adjtime覆盖先前的值。因此,当命令hwclock --adjust运行时,可以调整硬件时钟的漂移; 这也发生在关机时,但只有在hwclock守护进程被启用时,因此对于使用systemd的Arch系统,这不会发生。
注意:如果在上一次设置后不到24小时再次设置了hwclock,则不会重新计算漂移,因为hwclock考虑到经过的时间太短而无法准确计算漂移。

5. 参考及扩展阅读

原文:https://wiki.archlinux.org/index.php/System_time

5.1 时间同步[ 编辑]

网络时间协议(NTP)是用于通过分组交换,可变延迟数据网络同步计算机系统的时钟的协议。以下是Arch Linux可用的NTP实现:

  • ConnMan - 具有NTP支持的轻量级网络管理器。
https://01.org/connman || connman
http://www.ntp.org/ || NTP
  • sntp - NTPd附带的SNTP客户端。它取代了ntpdate,建议在非服务器环境中使用。
http://www.ntp.org/ || NTP
  • systemd-timesyncd - 一个只实现客户端的简单 SNTP守护进程,只关注从一个远程服务器查询时间。它应该适合大多数安装。
https://www.freedesktop.org/wiki/Software/systemd/ || systemd
  • OpenNTPD - OpenBSD项目的一部分,实现客户端和服务器。
http://www.openntpd.org/ || openntpd
  • Chrony - 漫游友好的客户端和服务器,专为不在线的系统而设计。
https://chrony.tuxfamily.org/ || chrony
  • ntpclient - 一个简单的命令行NTP客户端。
http://doolittle.icarus.com/ntpclient/ || ntpclient AUR

5.2 假hwclock [ 编辑]

alarm-fake-hwclock专为没有电池备份RTC的系统而设计,它包括一个systemd服务,在关机时保存当前时间并在启动时恢复节省的时间,从而避免奇怪的时间旅行错误。
安装 fake-hwclock-git AUR,启动并启用该服务fake-hwclock.service

https://wiki.gentoo.org/wiki/System_time
https://en.wikipedia.org/wiki/Network_Time_Protocol
https://linux.cn/lfs/LFS-BOOK-7.7-systemd/chapter07/clock.html
http://www.ntp.org/
更多关于Time的内容。
https://en.wikipedia.org/wiki/Time
https://zh.wikipedia.org/wiki/UTC%2B08:00
https://tycho.usno.navy.mil/systime.html
https://www.ucolick.org/~sla/leapsecs/timescales.html
https://en.wikipedia.org/wiki/International_Atomic_Time
https://en.wikipedia.org/wiki/Coordinated_Universal_Time
https://zh.wikipedia.org/wiki/氢原子钟
https://zh.wikipedia.org/wiki/铯
https://zh.wikipedia.org/wiki/铯钟