Elixir 的標準函式庫提供了 4 個處理日期與時間的模組,每個模組都有自己的結構。
Date模組。可以用~D sigil 建立Date結構。
~D[2021-01-01]
Time模組。可以用~T sigil 建立Time結構。
~T[12:00:00]
NaiveDateTime模組,用於沒有時區的日期時間。可以用~N sigil 建立NaiveDateTime結構。
~N[2021-01-01 12:00:00]
DateTime模組,用於帶有時區的日期時間。如果要用這個模組處理 UTC 以外的時區,就需要一個外部相依套件,也就是時區資料庫。
要互相比較日期或時間時,請在對應的模組中尋找compare或diff函式。像是==、>、<這類比較運算子看似可行,但它們對這些結構做不出正確的語意比較。
你那位在圖書館工作的朋友請你擴充她的圖書館軟體,讓它能自動計算逾期費用。 她目前的系統會把每本書借出時的確切日期與時間,以 ISO8601 日期時間字串的形式儲存起來。 她在迦納的一個小鎮經營地方圖書館,當地使用的是 GMT 時區(UTC +0),不實施日光節約時間,也不需要煩惱其他時區的問題。
實作LibraryFees.datetime_from_string/1函式。它應該接受一個 ISO8601 日期時間字串作為引數,並回傳一個NaiveDateTime結構。
LibraryFees.datetime_from_string("2021-01-01T13:30:45Z")
# => ~N[2021-01-01 13:30:45]
如果書是在中午前借出,讀者有 28 天的歸還期限;如果是在中午或中午之後借出,則是 29 天。
實作LibraryFees.before_noon?/1函式。它應該接受一個NaiveDateTime結構,並回傳布林值。
LibraryFees.before_noon?(~N[2021-01-12 08:23:03])
# => true
根據借出的日期時間,計算歸還日期。
實作LibraryFees.return_date/1函式。它應該接受一個NaiveDateTime結構,並回傳一個Date結構,也就是 28 或 29 天後的日期。
LibraryFees.return_date(~N[2020-11-28 15:55:33])
# => ~D[2020-12-27]
圖書館對逾期歸還採單一費率。為了計算費用,我們需要知道書實際歸還時,距離歸還日期已經過了幾天。
實作LibraryFees.days_late/2函式。它應該接受兩個引數:一個Date結構,也就是預計的歸還日期;以及一個NaiveDateTime結構,也就是實際歸還的日期時間。
如果實際歸還日期早於或等於預計的歸還日期,函式應該回傳 0;否則,函式應該回傳這兩個日期相差的天數。
圖書館會為了統計用途記錄書實際歸還的日期與時間,但計算逾期費用時不會用到時間。
LibraryFees.days_late(~D[2020-12-27], ~N[2021-01-03 09:23:36])
# => 7
圖書館有星期一還書的特別優惠。
實作LibraryFees.monday?/1函式。它應該接受一個NaiveDateTime結構,並回傳布林值。
LibraryFees.monday?(~N[2021-01-03 13:30:45Z])
# => false
實作LibraryFees.calculate_late_fee/3函式。它應該接受三個引數:兩個 ISO8601 日期時間字串,分別是借出的日期時間與實際歸還的日期時間,以及一天的逾期費用。它應該根據書實際逾期歸還的程度,回傳總逾期費用。
記得納入星期一的特別優惠。如果你在星期一還書,逾期費用可享半價,並無條件捨去。
# Sunday, 7 days late
LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-03T13:30:45Z", 100)
# => 700
# one day later, Monday, 8 days late
LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-04T09:02:11Z", 100)
# => 400