跳转到内容

newLISP 简介/日期和时间操作

来自维基教科书,开放世界中的开放书籍

日期和时间操作

[编辑 | 编辑源代码]

日期和时间函数

[编辑 | 编辑源代码]

要操作日期和时间,请使用以下函数:

  • date 将秒数转换为日期/时间,或返回当前日期/时间
  • date-value 返回自 1970-1-1 以来某个日期和时间的秒数,或者返回当前时间
  • now 在一个列表中返回当前日期/时间信息
  • time-of-day 返回自今日开始至今的毫秒数

date-valuenow 工作在 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 单独使用将为您提供本地时区的当前日期和时间(nowdate-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

[编辑 | 编辑源代码]

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

有关这些函数用法的另一个示例,请参阅 简单倒计时器

华夏公益教科书