# Time (简体中文)

相关文章

- 网络时间协议

翻译状态： 本文是英文页面 Time 的翻译，最后翻译时间：2013-05-15，点击这里可以查看翻译后英文页面的改动。

一个操作系统通过如下内容确定时间：时间数值、时间标准、时区和夏令时调节(中国已经废止)。本文分别介绍各个部分的定义及如何设置他们。要维护准确的系统时间，请参考 网络时间协议 一文。

## 硬件时钟和系统时钟

系统用两个时钟保存时间：硬件时钟和系统时钟。

硬件时钟(即实时时钟 RTC 或 CMOS 时钟)仅能保存：年、月、日、时、分、秒这些时间数值，无法保存时间标准(UTC 或 localtime)和是否使用夏令时调节。

系统时钟(即软件时间) 与硬件时间分别维护，保存了：时间、时区和夏令时设置。Linux 内核保存为自 UTC 时间 1970 年1月1日经过的秒数。初始系统时钟是从硬件时间计算得来，计算时会考虑`/etc/adjtime`的设置。系统启动之后，系统时钟与硬件时钟独立运行，Linux 通过时钟中断计数维护系统时钟。

因为系统时间是按 32 为整数保存的，最大只能记到 2038 年，所以 32 位 Linux 系统将在 2038 年停止工作。

### 读取时间

下面命令可以获得硬件时间和系统时间(硬件时钟按 localtime 显示):

    $ timedatectl status

### 设置时间

设置系统时间：

    # timedatectl set-time "2012-10-30 18:17:16"

### RTC clock

大部分操作系统的时间管理包括如下方面：

- 启动时根据硬件时钟设置系统时间
- 运行时通过 NTP 守护进程联网校正时间
- 关机时根据系统时间设置硬件时间。

## 时间标准

时间表示有两个标准：localtime 和 UTC(Coordinated Universal Time) 。UTC 是与时区无关的全球时间标准。尽管概念上有差别，UTC 和 GMT (格林威治时间) 是一样的。localtime 标准则依赖于当前时区。

时间标准由操作系统设定，Windows 默认使用 localtime，Mac OS 默认使用 UTC 而 UNIX 系列的操作系统两者都有。使用 Linux 时，最好将硬件时钟设置为 UTC 标准，并在所有操作系统中使用。这样 Linux 系统就可以自动调整夏令时设置，而如果使用 localtime 标准那么系统时间不会根据夏令时自动调整。

通过如下命令可以检查当前设置：

    $ timedatectl status | grep local

硬件时间可以用 `hwclock` 命令设置，将硬件时间设置为 localtime：

    # timedatectl set-local-rtc 1

硬件时间设置成 UTC：

    # timedatectl set-local-rtc 0

上述命令会自动生成`/etc/adjtime`，无需单独设置。

系统启动装入 rtc 驱动时可能会根据系统时钟设置硬件时钟。是否设置依赖于平台、内核版本和内核编译选项。如果进行了设置，此时会假定硬件时钟为 UTC 标准，`/sys/class/rtc/rtcN/hctosys`(N=0,1,2,..) 会设置成 1。后面 systemd 会根据`/etc/adjtime`重新设置。所以讲硬件时间设置为 localtime 会在启动时导致某些莫名其妙的问题，往回设置系统时间一般都是不安全的。

### Windows 系统使用 UTC

使用 `regedit`,输入如下 DWORD 值：

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

设置成十六进制 或者使用一个reg文件搞定：

    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
        "RealTimeIsUniversal"=dword:00000001

1. Windows XP 和 Windows Vista SP1 支持设置系统时间标准为 `UTC`，但是休眠待机的时候会把系统重新设置为 localtime，这是一个bug。推荐这些操作系统设置为 `localtime`.

如果 Windows 要求根据夏令时更新时钟，可以允许。时钟仍然是 UTC，仅是显示时间会改变。

设置时间标准后需要重新设置硬件时间和系统时间。

最好禁用Windows的时间同步功能，否则硬件时间可能混乱。

## 时区

检查当前时区：

    $ timedatectl status

显示可用时区：

    $ timedatectl list-timezones

修改时区：

    # timedatectl set-timezone <Zone>/<SubZone>

例如：

    # timedatectl set-timezone Asia/Shanghai

此命令会创建一个`/etc/localtime`软链接，指向`/usr/share/zoneinfo/`中的时区文件，如果手动创建此链接请确保是相对链接而不是绝对链接，参阅archlinux(7).

See `man 1 timedatectl`, `man 5 localtime`, and `man 7 archlinux` for more details.

Note: If the pre-systemd configuration file `/etc/timezone` still exists in your system, you can remove it safely, since it is no longer used.

## Time Skew

最能代表”真实时间“的是国际原子时钟)，所有的时钟都是有误差的。电子时钟的时间是不准的，但是一般有固定的偏移。这种于基值的差称为 'time skew' 或 '时间偏移'。用 `hwclock` 设置硬件时间时，会计算每天偏移的秒数。偏移值是原硬件时间与新设置硬件时间的差，并且考虑上次硬件时间设置时的偏移。新的偏移值会在设置时钟时写到文件 `/etc/adjtime` 。

注意: 如果硬件时间值与原值的差小于 24 小时，偏移量不会重新计算，因为时间过短，无法精确设置偏移。

如果硬件时钟总是过快或过慢，可能是计算了错误的偏移值。硬件时钟设置错误或者时间标准与其他操作系统不一致导致。删除文件 `/etc/adjtime` 可以删除偏移值，然后设置正确的硬件时钟和系统时钟，并检查时间标准是不是设置正确。

注意: 使用 Systemd 时，要使用 `/etc/adjtime`中的 drift 值(即无法或不想使用 NTP 时); 需要每次调用 `hwclock --adjust`命令，可以通过 cron 任务实现。

提高系统时间精度的方法有：

- NTP 可以通过网络时间协议同步 Linux 系统的时间。NTP 也会修正中断频率和每秒滴答数以减少时间偏移。并且每隔 11 分钟同步一次硬件时钟。
- AUR 中的 adjtimex 也可以调整内核时间参数，如中断频率等，提升系统时钟的频率。

## 外部资源

- Linux Tips - Linux, Clocks, and Time
- Sources for Time Zone and Daylight Saving Time Data for tzdata
- Time Scales
- Wikipedia:Time

Categories:

- Mainboards and BIOS (简体中文)
- System administration (简体中文)