#:g1: timeの紹介

Posted 2014-03-03 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の63日目です。

timeとはなにか

 timeは、MIT系Lispマシンや、NILで利用された時刻系のユーティリティパッケージです。
タイムスタンプ等をみるに1978、9年辺りから開発が始まっているようです。

パッケージ情報

パッケージ名time
参考サイトLisp Machine Manual: Dates and Times

インストール方法

 MIT系Lispマシンのソースが転がっているので、その中から探して移植してみましょう。

 自分が適当にCommon Lispに移植してASDFに対応したものがあるので、興味のある方はどうぞ。

 Quicklispのlocal-projectsディレクトリの中に設置して

(ql:quickload :lambda.time)

でロードできると思います。

試してみる

時刻の表示

 time:*default-date-print-mode*に形式を設定することで表示形式は変更できます。
大別してuniversal timeを与えるものと日時を与えるものの2種があります。

(time:print-current-time)
;>>  22-Feb-14 23:18:58
;=>  NIL

(time:print-time 0 0 0 1 1 1900)
;>>  1-Jan-1900 00:00:00
;=>  NIL

(time:print-universal-time (get-universal-time)) ;>> 22-Feb-14 23:19:06 ;=> NIL

time:*default-date-print-mode* ;=> :DD-MMM-YY

(time:print-brief-universal-time (get-universal-time)) ;>> 23:19 ;=> NIL

(time:print-current-date) ;>> Saturday the twenty-second of February, 2014; 11:22:20 pm ;=> NIL

(time:print-date 0 0 0 1 1 1900 1) ;>> Tuesday the first of January, 1900; 12:00:00 midnight ;=> NIL

(time:print-universal-date (get-universal-time)) ;>> Saturday the twenty-second of February, 2014; 11:19:52 pm ;=> NIL

時刻のパーズ

 時刻表現をパーズしてuniversal timeにしたりするものです。
様々な形式に対応しています。


(time:parse "Today")
;=>  0
;    0
;    0
;    22
;    2
;    2014
;    5
;    T
;    :RELATIVE

(map nil (lambda (d) (format T "~A~42T=> ~A~%" d (*:when-let (ut (ignore-errors (time:parse-universal-time d))) (*:date-string ut)))) '("March 15, 1960" "3/15/60" "3/15/1960" "15 March 1960" "15/3/60" "15/3/1960" "March-15-60" "3-15-60" "3-15-1960" "15-March-60" "15-3-60" "15-3-1960" "15-Mar-60" "3-15" "15 March 60" "Fifteen March 60" "The Fifteenth of March, 1960;" "Friday, March 15, 1980" "1130." "11:30" "11:30:17" "11:30 pm" "11:30 AM" "1130" "113000" "11.30" "11.30.00" "11.3" "11 pm" "12 noon" "midnight" "m" "6:00 gmt" "3:00 pdt" ;; any date format may be used with any time format "One minute after March 3, 1960" ;; meaning one minute after midnight "Two days after March 3, 1960" "Three minutes after 23:59:59 Dec 31, 1959"

"Now" "Today" "Yesterday" "five days ago" "two days after tomorrow" "the day after tomorrow" "one day before yesterday" "BOB@OZ's birthday")) ;>> March 15, 1960 => Tue 15 Mar 1960 00:00:00 ;>> 3/15/60 => Mon 15 Mar 2060 00:00:00 ;>> 3/15/1960 => Tue 15 Mar 1960 00:00:00 ;>> 15 March 1960 => Tue 15 Mar 1960 00:00:00 ;>> 15/3/60 => Mon 15 Mar 2060 00:00:00 ;>> 15/3/1960 => Tue 15 Mar 1960 00:00:00 ;>> March-15-60 => Mon 15 Mar 2060 00:00:00 ;>> 3-15-60 => Mon 15 Mar 2060 00:00:00 ;>> 3-15-1960 => Tue 15 Mar 1960 00:00:00 ;>> 15-March-60 => Mon 15 Mar 2060 00:00:00 ;>> 15-3-60 => Mon 15 Mar 2060 00:00:00 ;>> 15-3-1960 => Tue 15 Mar 1960 00:00:00 ;>> 15-Mar-60 => Mon 15 Mar 2060 00:00:00 ;>> 3-15 => Sat 15 Mar 2014 00:00:00 ;>> 15 March 60 => Mon 15 Mar 2060 00:00:00 ;>> Fifteen March 60 => Mon 15 Mar 2060 00:00:00 ;>> The Fifteenth of March, 1960; => Tue 15 Mar 1960 00:00:00 ;>> Friday, March 15, 1980 => Sat 15 Mar 1980 00:00:00 ;>> 1130. => Mon 24 Feb 2014 11:30:00 ;>> 11:30 => Mon 24 Feb 2014 11:30:00 ;>> 11:30:17 => Mon 24 Feb 2014 11:30:17 ;>> 11:30 pm => Sun 23 Feb 2014 23:30:00 ;>> 11:30 AM => Mon 24 Feb 2014 11:30:00 ;>> 1130 => Mon 24 Feb 2014 11:30:00 ;>> 113000 => Mon 24 Feb 2014 11:30:00 ;>> 11.30 => Mon 24 Feb 2014 11:30:00 ;>> 11.30.00 => Mon 24 Feb 2014 11:30:00 ;>> 11.3 => Mon 24 Feb 2014 11:30:00 ;>> 11 pm => Sun 23 Feb 2014 23:00:00 ;>> 12 noon => Mon 24 Feb 2014 12:00:00 ;>> midnight => Mon 24 Feb 2014 00:00:00 ;>> m => Mon 24 Feb 2014 00:00:00 ;>> 6:00 gmt => Mon 24 Feb 2014 15:00:00 ;>> 3:00 pdt => Mon 24 Feb 2014 19:00:00 ;>> One minute after March 3, 1960 => Thu 3 Mar 1960 00:01:00 ;>> Two days after March 3, 1960 => Sat 5 Mar 1960 00:00:00 ;>> Three minutes after 23:59:59 Dec 31, 1959 => Fri 1 Jan 1960 00:02:59 ;>> Now => Sun 23 Feb 2014 15:07:57 ;>> Today => Sun 23 Feb 2014 00:00:00 ;>> Yesterday => Sat 22 Feb 2014 00:00:00 ;>> five days ago => Tue 18 Feb 2014 15:07:57 ;>> two days after tomorrow => Wed 26 Feb 2014 00:00:00 ;>> the day after tomorrow => Tue 25 Feb 2014 00:00:00 ;>> one day before yesterday => Fri 21 Feb 2014 00:00:00 ;>> BOB@OZ's birthday => NIL ;>> ;=> NIL

"BOB@OZ's birthday"がNILになってしまっていますが、移植したものが対応していないだけで、実機ではfingerした結果を表示するような実装になっています。
fingerで誕生日が取得できたという牧歌的な時代の機能という感じですね。

時間間隔

 時間の間隔を扱うものです、表示とパーズそれぞれが用意されています。

(time:print-interval-or-never 4)
;>>  4 seconds
;=>  NIL

(mapcar #'time:parse-interval-or-never '("4 seconds" "4 secs" "4 s" "5 mins 23 secs" "5 m 23 s" "23 SECONDS 5 M" "3 yrs 1 week 1 hr 2 mins 1 sec" "never" "not ever" "no" "")) ;=> (4 4 4 323 323 323 95216521 NIL NIL NIL NIL)

その他

 その他にも細々と色々あります。

(time:month-length 2 2014)
;=>  28

(time:leap-year-p 2000) ;=> T (time:day-of-the-week-string 0) ;=> "Monday"

(mapcar (lambda (x) (time:day-of-the-week-string 0 x)) '(:long :short :medium :french :german :italian)) ;=> ("Monday" "Mon" "Mon" "Lundi" "Montag" "Lunedi")

(mapcar (lambda (x) (time:month-string 2 x)) '(:long :short :medium :french :german :italian)) ;=> ("February" "Feb" "Feb" "Fevrier" "Februar" "Febbraio")

まとめ

 今回は、timeを紹介してみました。
なんとなくFORMATやLOOPに通じるMIT臭を感じることができたのではないでしょうか。
骨董趣味で復活させてみたライブラリですが、自分は割と便利に使っています。

comments powered by Disqus