在 Common Lisp 中,时间有四种表示方式,这里只会涉及其中两种。
1900-01-01T00:00:00Z以来的秒数(也就是 1900 年 1 月 1 日 UTC 时间的午夜)。要获取当前的通用时间,可以使用get-universal-time或get-decoded-time。
前者返回自1900-01-01T00:00Z以来的当前秒数,后者以解码格式返回同样的数据。
decode-universal-time和encode-universal-time是处理时间的主要函数。
前者接受一个通用时间,并以多值的形式返回一个解码时间值;后者接受各个解码时间值作为实参,返回一个通用时间。
两者都接受一个可选的时区实参。 时区的格式见下文。
解码时间是一组值:
1/3600的整数倍(encode-universal-time 1 2 3 4 5 2000 0) ; => 3166398121
(decode-universal-time 3166398121) ; => 1
; 2
; 3
; 4
; 5
; 2000
; 3 (Thursday)
; NIL
; 0
(decode-universal-time 2208988800) ; => 0
; 0
; 0
; 1
; 1
; 1970
; 3
; NIL
; 0
在 Common Lisp 中,函数不仅能返回一个值,还能返回多个值。
例如floor会向零的方向取整,它返回两个值,第一个是取整后的值,第二个是余数。
(floor 3.5) ; => 3
; 0.5
(下面我们会把返回的多个值分行展示。)
如果你想让一个函数返回多个值,可以使用values访问器:
(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
; 2
; 3
如果你只关心第一个值,那就不需要做任何特殊处理,语言会自动帮你处理好:
(+ (values 1 2 3) (values 10 20 30)) ; => 11
不过,如果你想访问其他那些值,就需要用到几个函数。
两个主要的宏是multiple-value-list和multiple-value-bind。
它们用来包裹返回多个值的表达式,并捕获所有的值。
第一个会创建一个包含所有值的列表。
第二个让你把变量绑定到各个值上。
(multiple-value-list (values 1 2 3)) ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3)
(+ a b c)) ; => 6
另一个有用的函数是nth-value
Lisp Aliens 喜欢庆祝周年纪念日。 在他们看来,重要的周年纪念日是十亿秒。 也就是:从事件发生起经过 1,000,000,000 秒。
写一个函数from,它接受 6 个参数:year、month、day、hour、min、sec,并计算十亿秒纪念日的日期和时间。
这个函数应以数组的形式返回日期,顺序和含义与输入的参数一致。
(from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40)