學習軌道
/
Common Lisp
Common Lisp
/
練習
/
十億秒週年
十億秒週年

十億秒週年

學習練習

簡介

日期與時間

在 Common Lisp 中,時間有四種表示方式,這裡會介紹其中兩種。

  • 通用時間是一種絕對時間,是一個整數,代表自1900-01-01T00:00:00Z(也就是 UTC 時間 1900 年 1 月 1 日的午夜)起算的秒數。
  • 解碼時間是由 9 個值組成的元組,這些值共同代表某個特定的日曆時間:秒、分、時、日、月、年、星期、日光節約時間旗標、時區。 (詳見下文。)

通用時間

要取得目前的通用時間,可以使用get-universal-time或get-decoded-time。 前者回傳自1900-01-01T00:00Z起算的目前秒數,後者則以解碼格式回傳同樣的資料。

解碼時間

decode-universal-time和encode-universal-time是處理時間的主要函式。 前者接受一個通用時間,並以多重值的形式回傳解碼時間值;後者接受解碼時間的各個值作為引數,回傳一個通用時間。

兩者都接受一個選用的時區引數。 時區的格式請見下文。

解碼時間是一組值:

  • 秒:0 到 59 之間的整數
  • 分:0 到 59 之間的整數
  • 時:0 到 23 之間的整數
  • 日:1 到 31 之間的整數(上限當然取決於月份和年份)
  • 月:1 到 12 之間的整數
  • 年:代表年份的整數。
  • 星期:0 到 6 之間的整數。0 代表星期一,1 代表星期二,依此類推……6 代表星期日。
  • 日光節約時間旗標:值為 true 表示日光節約時間正在實施。
  • 時區:介於 -24 與 24 之間的數字,代表與 UTC 的時差。 這個數字是有理數,且必須是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 外星人喜歡慶祝週年紀念。對他們來說,重要的週年紀念日就是十億秒。也就是從事件發生起算的 1,000,000,000 秒。

1. 計算十億秒週年紀念的日期

寫一個函式from,接受 6 個參數:year、month、day、hour、min、sec,並計算出十億秒週年紀念的日期與時間。這個函式應該以一個陣列回傳日期,其順序與意義和輸入的參數相同。

(from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40)
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Common Lisp Exercism

準備好開始 十億秒週年 了嗎?

註冊 Exercism,透過 27 個概念92 個練習 和真人引導來學習並精通 Common Lisp,全部免費。