newLISP 简介/日期和时间操作
要操作日期和时间,请使用以下函数:
- date 将秒数转换为日期/时间,或返回当前日期/时间
- date-value 返回自 1970-1-1 以来某个日期和时间的秒数,或者返回当前时间
- now 在一个列表中返回当前日期/时间信息
- time-of-day 返回自今日开始至今的毫秒数
date-value 和 now 工作在 UT 中,而不是您的本地时间。date 可以考虑您的本地时间与 UT 之间的时间差。
所有四个函数都可以用来返回当前时间的信息。date-value 返回 1970 年与当前时间(UT)之间的秒数
1142798985
而 now 返回一个包含当前日期和时间信息(UT)的整数列表
(now)
;-> (2006 3 19 20 5 2 125475 78 1 0 0)
这提供了以下信息:
- 年、月、日 (2006, 3, 19)
- 时、分、秒、微秒 (20, 5, 2, 125475)
- 当前年份中的日期 (78)
- 当前星期中的日期 (1)
- 本地时区偏移量(以分钟计,西经 GMT)(0)
- 夏令时标志 (0)
要提取您想要的信息,请使用切片或挑选出元素
(slice (now) 0 3) ; year month day using explicit slice
(0 3 (now)) ; year month day using implicit slice
(select (now) '(0 1 2)) ; year month day using selection
(3 3 (now)) ; hour minute second
(nth 8 (now)) ; day of the week, starting from Sunday
date 单独使用将为您提供本地时区的当前日期和时间(now 和 date-value 返回的是 UCT/UTC 值,而不是相对于您的本地时区)
(date)
;-> "Mon Mar 19 20:05:02 2006"
它还可以告诉您自 1970 年(Unix 纪元开始)以来的某个整数秒数的日期,并根据您的本地时区进行调整
(date 0) ; a US newLISP user sees this
;-> "Wed Dec 31 16:00:00 1969"
(date 0) ; a European newLISP user sees this
;-> "Thu Jan 1 01:00:00 1970"
date-value 可以计算特定日期或日期/时间(UT)的秒数
(date-value 2006 5 11) ; just the date
;-> 1147305600
(date-value 2006 5 11 23 59 59) ; date and time (in UT)
;-> 1147391999
因为 date-value 可以接受年、月、日、时、分和秒作为输入,所以它可以应用于 now 的输出
(apply date-value (now))
;-> 1164723787
通过将不同的时间转换为这些日期值,您可以进行计算。例如,要从 2005 年 1 月 3 日减去 2003 年 11 月 13 日
(- (date-value 2005 1 3) (date-value 2003 11 13))
;-> 36028800
; seconds, which is
(/ 36028800 (* 24 60 60))
;-> 417
; this is a duration in days - don't convert this to a date!
您可以通过将 12 天的秒数加到该日期来找出 2005 年圣诞节后的第 12 天的日期
(+ (date-value 2005 12 25) (* 12 24 60 60))
; seconds in 12 days
;-> 1136505600
; this is an instant in time, so it can be converted!
这个秒数值可以通过 date 以更长的形式转换为人们可以理解的日期,当它接受一个自 1970 年以来的秒数值,并将它转换为基于 UT 值的本地时区表示
(date 1136505600)
;-> "Fri Jan 6 00:00:00 2006" ; for this European user...
当然 (date (date-value)) 与 (date) 相同,但如果您想更改日期格式,则必须使用更长的形式。date 接受一个额外的格式字符串(以分钟为单位的时间偏移量为前缀)。如果您熟悉 C 语言风格的 strftime 格式,您将知道该怎么做
(date (date-value) 0 "%Y-%m-%d %H:%M:%S") ; ISO 8601
;-> 2006-06-08 11:55:08
(date 1136505600 0 "%Y-%m-%d %H:%M:%S")
;-> "2006-01-06 00:00:00"
(date (date-value) 0 "%Y%m%d-%H%M%S") ; in London
;-> "20061207-144445"
(date (date-value) (* -8 60) "%Y%m%d-%H%M%S") ; in Los Angeles
;-> "20061207-064445" ; 8 hours offset
parse-date 函数(不幸的是,在 Windows 上不可用)可以将日期和时间字符串转换为自 1970 年以来的秒数值。您在字符串之后提供一个日期时间格式字符串
(parse-date "2006-12-13" "%Y-%m-%d")
;-> 1165968000
(date (parse-date "2007-02-08 20:12" "%Y-%m-%d %H:%M"))
;-> "Thu Feb 8 20:12:00 2007"
为了计时,您可以使用以下函数:
- time 返回评估表达式所花费的时间,以毫秒为单位
- timer 设置一个计时器,等待一定秒数,然后评估表达式
- sleep 停止工作一定毫秒数
time 有助于找出表达式评估花费的时间
(time (read-file "/Users/me/Music/iTunes/iTunes Music Library.xml"))
;-> 27 ; milliseconds
您也可以提供重复次数,这可能会提供更准确的结果
(time (for (x 1 1000) (factor x)) 100) ; 100 repetitions
;-> 426
如果您不能或不想包含表达式,则可以使用 time-of-day 进行更简单的计时
(set 'start-time (time-of-day))
(for (i 1 1000000)
(set 'temp (sqrt i)))
(string {that took } (div (- (time-of-day) start-time) 1000) { seconds})
;-> "that took 0.238 seconds"
timer 本质上是一个闹钟。设置它,然后直到时间到来就不用管它。您提供一个指定警报操作的符号,然后是等待的秒数
(define (teas-brewed)
(println (date) " Your tea has brewed, sir!"))
(timer teas-brewed (* 3 60))
三分钟后,您将看到以下内容:
Sun Mar 19 23:36:33 2006 Your tea has brewed, sir!
如果没有参数,此函数将返回已分配为警报操作的当前符号的名称
(timer)
;-> teas-brewed
如果您正在等待警报响起,并且您迫不及待地想知道到目前为止已经过去了多少时间,请使用带分配符号名称但没有秒数值的函数
(timer teas-brewed)
;-> 89.135747
; waited only a minute and a bit so far
有关这些函数用法的另一个示例,请参阅 简单倒计时器。