43.5 时刻

本节说明如何获取当前时间与时区。

包括 current-timefile-attributes 在内的许多函数,会返回 Lisp 时间戳,其以秒为单位计数,并可通过自 纪元(epoch) 1970-01-01 00:00:00 UTC(协调世界时)起的秒数表示绝对时间。通常这类计数会忽略闰秒;不过 GNU 及部分其他操作系统可配置为计入闰秒。

尽管传统上 Lisp 时间戳为整数对,但其格式已有所演变,程序一般不应依赖当前默认格式。若程序需要特定的时间戳格式,可使用 time-convert 函数转换为所需格式。See 时间转换

当前 Lisp 时间戳有三种形式,均以秒数表示时间:

函数参数(例如 format-time-stringtime 参数)接受更通用的 时间值(time value) 格式,可以是 Lisp 时间戳、表示当前时间的 nil、表示秒数的有限浮点数,或是截断后的列表时间戳 (high low micro)(high low),缺失分量视为 0。

时间值可与日历格式及其他格式相互转换。部分转换依赖操作系统函数,这些函数会限制时间值的范围,超出限制时会抛出如 ‘"Specified time is not representable"’ 之类的错误。 例如,部分系统可能不支持纪元之前或遥远未来的时间戳。 你可以使用 format-time-string 将时间值转换为人类可读字符串,使用 time-convert 转换为 Lisp 时间戳,使用 decode-timefloat-time 转换为其他格式。这些函数将在后续小节说明。

Function: current-time-string &optional time zone

该函数以人类可读字符串形式返回当前日期与时间。字符串开头部分的格式固定,依次为星期、月份、日期、时刻;这些字段占用的字符数始终相同。不过(除非你需要无视区域设置而强制使用英文星期或月份缩写),通常使用 format-time-string 比从 current-time-string 输出中提取字段更方便,因为年份未必是四位数字,且未来可能在末尾追加额外信息。

参数 time(若指定)表示要格式化的时间,而非当前时间。可选参数 zone 默认为当前时区规则。See 时区规则。操作系统会限制时间与时区值的范围。

(current-time-string)
     ⇒ "Fri Nov  1 15:59:49 2019"
Variable: current-time-list

该布尔变量用于过渡兼容。若为 tcurrent-time 及相关函数返回列表格式的时间戳,通常为 (high low micro pico);否则使用 (ticks . hz) 格式。当前该变量默认为 t,以保持与旧版 Emacs 行为兼容。建议开发者将该变量设为 nil 测试与时间戳相关的代码,因为未来 Emacs 版本会将其默认值改为 nil,并在后续版本中移除。

Function: current-time

该函数以 Lisp 时间戳形式返回当前时间。 若 current-time-listnil,时间戳格式为 (ticks . hz),其中 ticks 为时钟滴答数,hz 为每秒滴答数。 否则时间戳为列表格式 (high low usec psec)。 你可以使用 (time-convert nil t)(time-convert nil 'list) 获取指定格式,不受 current-time-list 取值影响。See 时间转换

Function: float-time &optional time

该函数以浮点数形式返回自纪元起的当前秒数。可选参数 time(若指定)表示要转换的时间,而非当前时间。

警告:由于结果为浮点数,可能存在精度损失。若需要精确时间戳,请勿使用该函数。例如,在典型系统上 (float-time '(1 . 10)) 显示为 ‘0.1’,但实际值略大于 1/10。

time-to-seconds 是该函数的别名。

Function: current-cpu-time

返回当前 CPU 时间及其精度。返回值为对 (CPU-TICKS . TICKS-PER-SEC)CPU-TICKS 计数器可能回绕,因此间隔过久的数值无法有效比较。