第十一章 保持时间

 

“时间是一种幻觉,午餐时间更是如此。” Douglas Adams.

本章解释了Linux系统是如何维护[或保持]时间的,以及需要做些什么来避免引起麻烦。通常,关于时间你用不着做什么事,但理解它是很有好处的。

 

时区(Time zones

时间的度量主要是基于有规则的自然现象,比如行星的旋转导致了有白天和黑夜的交替周期。两个连续周期所用的总时间是个常数,但是白天以及黑夜的周期长度却是在变化。一个简单的常数例子是正午。

正午是一天中太阳离地面位置最高时的时刻。由于地球是圆的,[1]正午在不同的地方有不同的时刻。这致使有了当地时间local time)的概念。人们用许多单位来度量时间,其中许多的度量单位都与自然现象相关,如正午。只要你待在同一个地方,就用不着关心有不同的当地时间。

在你需要与远地通信的时候,你就会注意到需要一个共同的时间。在现代时期,世界上的许多地方都在相互通信,于是,定义了一个度量时间的全球标准。这个时间称为世界时(universal timeUTUTC,以前以格林威治平均时间Greenwich Mean TimeGMT,因为这在英格兰格林威治是当地时间)。当有不同当地时间的人进行通信时,他们就能用世界时来表达时间了。这样就不会混淆事情应在什么时候发生了。

每个当地时间都称为一个时区[time zone]。虽然地理上理应所有正午时刻相同的地方属于同一个时区,但是政治使它变的复杂。由于各种原因,许多国家使用夏令时(daylight savings time),他们调整时钟使工作时获得更多的日光,然后在冬天时把时钟调回。别的国家不这样做。那些这样做的国家,常常争执什么时候调整时钟,而且他们几乎年年改变规则。这使得时区的转换非常的不易。

时区最好是以地理位置命名或者是通过告知当地与世界时之差的方法。在美国和一些其他国家,当地时间都有一个名字以及三个字母的缩写。但是,缩写不是唯一的,并且除非与国家名连用,否则不宜使用。最好使用当地名称,如赫尔辛基,来谈论当地时间而不要用东欧时间(East European time)。因为不是所有的东欧国家都遵循同样的规律的。

Linux有一个时区软件包,里面包括所有的现存时区,而且当规则改变时能够很容易更新。每个系统管理员所需做的就是选择合适的时区。同样,每个用户可以设置自己的时区;这显的很重要,因为许多使用计算机的人是通过internet网来自不同的国家。当你本地时区的夏令时规定改变时,一定至少要更新Linux系统中是那个部分。除了设置系统时区和更新时区数据文件以外,很少要为时间方面烦恼的。

 

硬件和软件时钟

    个人计算机有一颗电池来驱动硬件时钟,这颗电池确保即使在计算机的其它部分没有电时时钟也能工作。硬件时钟可以从BIOS的设置屏幕上或从正在运行的操作系统中进行设置。

Linux内核从硬件时钟上直接取得时间。在引导期间,Linux将自己的时钟设置成与硬件时钟同步。在这以后,两个时钟都独立地运行。Linux维持着自己的时钟,因为读取硬件时钟是很慢的并且也比较复杂。

内核时钟总是显示世界时。这样,内核就根本不需要知道什么时区。这种简明性导致高可靠性并使得更新时区信息变得很容易。每一个进程独自处理时区的转换(使用属于时区软件包中的标准工具)。

硬件时钟可以是本地时间也可以是世界时。通常将硬件时钟设置成世界时更好一些,因为这样当夏令时开始或结束时你就不需要调整硬件时钟了(UTC没有DST)。不幸的是,有些PC操作系统,包括MS-DOSWindowsOS/2,假设硬件时钟显示的是本地时间。Linux对于这两者都可以处理,但如果硬件时钟显示本地时间时,那么,在夏令时开始和结束时都需要调整它(否则,它将不会显示本地时间)。

 

显示和设置时间

Debian系统中,系统时区由符号连接/etc/localtime确定。这个连接指向描述本地时区的时区数据文件。时区数据文件存储于/usr/lib/zoneinfo中。其它Linux发行版做法可能不同。

一个用户可以通过设置TZ环境变量来改变他的私有时区。如果TZ没有被设置,就使用系统时区。TZ变量的语法在tzsetmanual page中有描述。

date命令用于显示当前日期和时间。[2] 例如:

$ date

Sun Jul 14 21:53:41 EET DST 1996

$

那个时间是星期日,714日,1996年,在大概晚上十点差十分钟,在称为“EET DST”的时区(可能是指东欧夏令时)。date也可用来显示世界时:

$ date -u

Sun Jul 14 18:53:42 UTC 1996

Sun Jul 14 18:53:42 UTC 1996

$

date也同样用于设置内核软件时钟:

# date 07142157

Sun Jul 14 21:57:00 EET DST 1996

# date

Sun Jul 14 21:57:02 EET DST 1996

#

详细资料参见datemanual page;语法有些深奥而难懂。只有超级用户root能设置时间。虽然每个用户可以有他自己的时区,但时钟对每个人来说是一样的。

date仅显示或设置软件时钟。而clock命令用于同步软件时钟和硬件时钟。它用于系统引导时,读取硬件时钟并设置软件时钟。如果你需要设置这两个时钟,首先要用date来设置软件时钟,然后用clock –w来设置硬件时钟。

clock命令的-u选项告诉系统硬件时钟是世界时。你必须正确地使用-u选项,否则的话,你的计算机系统会对这个时间到底是什么感到困惑。

更改时钟要小心,Unix系统的许多部分需要正确工作的时钟。例如,cron后台程序周期性地运行命令。如果你更改了时钟值,那么它会对是否要运行那些命令感到困惑。在早期的Unix系统上,有人把时钟设快了二十年,这时cron就想要一次性地立刻运行所有二十年的周期命令。目前的cron版本能够正确地处理这个问题,但你仍需要小心。时间上的大的向前或向后跳跃要比小的或向前的跳跃危险的多。

 

当时钟不准时

Linux软件时钟并不总是精确的。它是由PC硬件产生的周期性的定时器中断(timer interrupt来工作的。如果系统运行了太多的进程,它就需要较长的时间来执行定时器中断程序,并且软件时钟就会漏掉一些中断。硬件时钟是独立运行的,通常比较精确。如果你经常重新引导你的计算机(对于大多数不是服务器的系统通常如此),它通常能保持较精确的时间。

如果你需要调整硬件时钟,最简单的办法是重新引导机器,进入BIOS的设置屏幕,并在那里来设置。这样做可以避免所有的改变系统时间可能带来的问题。如果不能从BIOS中来做的话,就用date以及clock来设置新时间(要按这个次序),并且如果系统的一些部分开始工作的很奇怪时,就要重新引导系统了。

一个连网的计算机(即使是通过modem连网的)能够通过比较自己的时间和网上其它计算机的时间来自动地检查自己的时钟。如果知道其它计算机有着非常精确的时间的话,那么大家都会有很精确的时间。这可以通过使用rdatenetdate命令来做到。这两个命令都会检测远程计算机上的时间(netdate能够操作几个远程计算机),并且将本地计算机的时间设置成和远程的一样。通过周期性地运行这些命令,你的计算机就能够保持和远程计算机同样精确的时间了。

XXX中有有关NTP智能的一些叙述。

 

注释

  1. 根据最近的调查。
  2. 要对time命令小心,它不显示当前时间。