本节说明如何获取当前时间与时区。
包括 current-time 和 file-attributes 在内的许多函数,会返回 Lisp 时间戳,其以秒为单位计数,并可通过自 纪元(epoch) 1970-01-01 00:00:00 UTC(协调世界时)起的秒数表示绝对时间。通常这类计数会忽略闰秒;不过 GNU 及部分其他操作系统可配置为计入闰秒。
尽管传统上 Lisp 时间戳为整数对,但其格式已有所演变,程序一般不应依赖当前默认格式。若程序需要特定的时间戳格式,可使用 time-convert 函数转换为所需格式。See 时间转换。
当前 Lisp 时间戳有三种形式,均以秒数表示时间:
(ticks . hz),其中 hz 为正数。表示 ticks/hz 秒,若 hz 为 1 则与普通 ticks 时间相同。hz 的常用值为 1000000000,对应纳秒精度时钟。
(high low micro pico),其中 0≤low<65536,0≤micro<1000000,0≤pico<1000000。
其表示的秒数计算公式为:
high * 2**16 + low + micro * 10**−6 + pico * 10**−12。
若 current-time-list 为 t,部分函数可能默认返回两元素或三元素列表,省略的 micro 与 pico 分量默认为 0。
在当前所有机器上 pico 均为 1000 的倍数,但随着更高精度时钟的普及,这一情况可能改变。
函数参数(例如 format-time-string 的 time 参数)接受更通用的 时间值(time value) 格式,可以是 Lisp 时间戳、表示当前时间的 nil、表示秒数的有限浮点数,或是截断后的列表时间戳 (high low micro) 或 (high low),缺失分量视为 0。
时间值可与日历格式及其他格式相互转换。部分转换依赖操作系统函数,这些函数会限制时间值的范围,超出限制时会抛出如 ‘"Specified time is not representable"’ 之类的错误。
例如,部分系统可能不支持纪元之前或遥远未来的时间戳。
你可以使用 format-time-string 将时间值转换为人类可读字符串,使用 time-convert 转换为 Lisp 时间戳,使用 decode-time 和 float-time 转换为其他格式。这些函数将在后续小节说明。
该函数以人类可读字符串形式返回当前日期与时间。字符串开头部分的格式固定,依次为星期、月份、日期、时刻;这些字段占用的字符数始终相同。不过(除非你需要无视区域设置而强制使用英文星期或月份缩写),通常使用 format-time-string 比从 current-time-string 输出中提取字段更方便,因为年份未必是四位数字,且未来可能在末尾追加额外信息。
参数 time(若指定)表示要格式化的时间,而非当前时间。可选参数 zone 默认为当前时区规则。See 时区规则。操作系统会限制时间与时区值的范围。
(current-time-string)
⇒ "Fri Nov 1 15:59:49 2019"
该布尔变量用于过渡兼容。若为 t,current-time 及相关函数返回列表格式的时间戳,通常为 (high low micro pico);否则使用 (ticks . hz) 格式。当前该变量默认为 t,以保持与旧版 Emacs 行为兼容。建议开发者将该变量设为 nil 测试与时间戳相关的代码,因为未来 Emacs 版本会将其默认值改为 nil,并在后续版本中移除。
该函数以 Lisp 时间戳形式返回当前时间。
若 current-time-list 为 nil,时间戳格式为 (ticks . hz),其中 ticks 为时钟滴答数,hz 为每秒滴答数。
否则时间戳为列表格式 (high low usec psec)。
你可以使用 (time-convert nil t) 或 (time-convert nil 'list) 获取指定格式,不受 current-time-list 取值影响。See 时间转换。
该函数以浮点数形式返回自纪元起的当前秒数。可选参数 time(若指定)表示要转换的时间,而非当前时间。
警告:由于结果为浮点数,可能存在精度损失。若需要精确时间戳,请勿使用该函数。例如,在典型系统上 (float-time '(1 . 10)) 显示为 ‘0.1’,但实际值略大于 1/10。
time-to-seconds 是该函数的别名。
返回当前 CPU 时间及其精度。返回值为对 (CPU-TICKS . TICKS-PER-SEC)。CPU-TICKS 计数器可能回绕,因此间隔过久的数值无法有效比较。