Moved test suite to subdirectory
This commit is contained in:
parent
c16f1f44e3
commit
66196d820f
4 changed files with 0 additions and 0 deletions
341
test/test-dates.lisp
Normal file
341
test/test-dates.lisp
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
;;; Copyright (c) 2017, Sudhir Shenoy. All rights reserved.
|
||||
|
||||
;;; Redistribution and use in source and binary forms, with or without
|
||||
;;; modification, are permitted provided that the following conditions
|
||||
;;; are met:
|
||||
|
||||
;;; * Redistributions of source code must retain the above copyright
|
||||
;;; notice, this list of conditions and the following disclaimer.
|
||||
|
||||
;;; * Redistributions in binary form must reproduce the above
|
||||
;;; copyright notice, this list of conditions and the following
|
||||
;;; disclaimer in the documentation and/or other materials
|
||||
;;; provided with the distribution.
|
||||
|
||||
;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
|
||||
;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
(in-package :cl-dates-test)
|
||||
|
||||
(deftest julian ()
|
||||
(check
|
||||
(= (ymd->date 2017 2 5) 2457789.5)
|
||||
(= (ymd->date 1959 12 29) 2436931.5)
|
||||
(= (ymd->date 1959 12 29 18 12 26.3) 2436932.2586376667d0)
|
||||
(equal '(2017 2 5) (multiple-value-call #'list (date->ymd 2457789.5)))
|
||||
(= (ymd->date 1600 2 29) 2305506.5)
|
||||
(= (ymd->date 1600 2 29 9 31 23.5) 2305506.896799773d0)
|
||||
(equal '(1600 2 29 9 31 23.500385284423828d0)
|
||||
(multiple-value-call #'list (date->ymd 2305506.896799773d0 :want-time t)))
|
||||
(= (date->javascript-time (ymd->date 2017 6 18)) 1497744000000)
|
||||
(= (jday-number (ymd->date 2017 6 18)) 2457923)))
|
||||
|
||||
(deftest misc-fns ()
|
||||
(check
|
||||
(valid-date-p 2000 2 29)
|
||||
(null (valid-date-p 1900 2 29))
|
||||
(null (valid-date-p 1234 65 789))
|
||||
|
||||
(null (leap-year-p 1900))
|
||||
(leap-year-p 2000)
|
||||
(null (leap-year-p 2001))
|
||||
(leap-year-p 2004)
|
||||
|
||||
(eq :monday (day-of-week (ymd->date 2017 2 6)))
|
||||
(eq :wednesday (day-of-week (ymd->date 1959 9 23)))
|
||||
|
||||
(= (nth-day-of-week (ymd->date 2017 2 5) :tuesday 3) (ymd->date 2017 2 21))
|
||||
(= (nth-day-of-week (ymd->date 2017 2 5) :thursday 3) (ymd->date 2017 2 16))
|
||||
;; overflow month - returns last tuesday
|
||||
(= (nth-day-of-week (ymd->date 2017 2 5) :tuesday 7) (ymd->date 2017 2 28))
|
||||
;; any number <= 1 should return 1st tuesday
|
||||
(= (nth-day-of-week (ymd->date 2017 2 5) :tuesday -7) (ymd->date 2017 2 7))
|
||||
|
||||
(= (first-of-next-month (ymd->date 2017 6 18)) (ymd->date 2017 7 1))
|
||||
(= (first-of-next-month (ymd->date 2016 12 18)) (ymd->date 2017 1 1))
|
||||
|
||||
(= (last-day-of-month (ymd->date 2016 12 18)) (ymd->date 2016 12 31))
|
||||
(= (last-day-of-month (ymd->date 2016 2 1)) (ymd->date 2016 2 29))
|
||||
(= (last-day-of-month (ymd->date 2017 2 1)) (ymd->date 2017 2 28))
|
||||
|
||||
(= (last-day-of-prev-month (ymd->date 2016 12 18)) (ymd->date 2016 11 30))
|
||||
(= (last-day-of-prev-month (ymd->date 2017 1 1)) (ymd->date 2016 12 31))
|
||||
(= (last-day-of-prev-month (ymd->date 2016 3 1)) (ymd->date 2016 2 29))
|
||||
(= (last-day-of-prev-month (ymd->date 2017 3 1)) (ymd->date 2017 2 28))
|
||||
|
||||
(date= (ymd->date 2007 2 3 10 35 42) (ymd->date 2007 2 3 11 30 20) (ymd->date 2007 2 3 12 45 12))
|
||||
(date/= (ymd->date 2007 2 4) (ymd->date 2007 2 3) (ymd->date 2007 2 3))
|
||||
(date< (ymd->date 2007 2 3 10 35 42) (ymd->date 2007 2 4 11 30 20) (ymd->date 2007 2 5 12 45 12))
|
||||
(not (date< (ymd->date 2007 2 3 10 35 42) (ymd->date 2007 2 3 11 30 20) (ymd->date 2007 2 5 12 45 12)))
|
||||
(date<= (ymd->date 2007 2 3 10 35 42) (ymd->date 2007 2 3 11 30 20) (ymd->date 2007 2 5 12 45 12))))
|
||||
|
||||
(deftest print-fns ()
|
||||
(let ((dt1 (ymd->date 2017 2 16))
|
||||
(dt2 (ymd->date 2017 2 16 17 30 25 +9)))
|
||||
(check
|
||||
(string= (dow->string :monday) "Monday")
|
||||
(string= (dow->string :tuesday) "Tuesday")
|
||||
(string= (dow->string :wednesday) "Wednesday")
|
||||
(string= (dow->string :thursday) "Thursday")
|
||||
(string= (dow->string :friday) "Friday")
|
||||
(string= (dow->string :saturday) "Saturday")
|
||||
(string= (dow->string :sunday) "Sunday")
|
||||
|
||||
(string= (month->string 1) "January")
|
||||
(string= (month->string 2) "February")
|
||||
(string= (month->string 3) "March")
|
||||
(string= (month->string 4) "April")
|
||||
(string= (month->string 5) "May")
|
||||
(string= (month->string 6) "June")
|
||||
(string= (month->string 7) "July")
|
||||
(string= (month->string 8) "August")
|
||||
(string= (month->string 9) "September")
|
||||
(string= (month->string 10) "October")
|
||||
(string= (month->string 11) "November")
|
||||
(string= (month->string 12) "December")
|
||||
|
||||
(string= (date->string dt1) "2017-02-16")
|
||||
(string= (date->string dt1 :format :iso-8601) "2017-02-16")
|
||||
(string= (date->string dt1 :format :asctime) "Thu Feb 16 2017")
|
||||
(string= (date->string dt1 :format :rfc-822) "Thu, 16 Feb 2017")
|
||||
(string= (date->string dt1 :format :rfc-850) "Thu, 16-Feb-2017")
|
||||
|
||||
(string= (date->string dt2) "2017-02-16 08:30:25 UTC")
|
||||
(string= (date->string dt2 :format :iso-8601) "2017-02-16T08:30:25Z")
|
||||
(string= (date->string dt2 :format :asctime) "Thu Feb 16 08:30:25 GMT 2017")
|
||||
(string= (date->string dt2 :format :rfc-822) "Thu, 16 Feb 2017 08:30:25 GMT")
|
||||
(string= (date->string dt2 :format :rfc-850) "Thu, 16-Feb-2017 08:30:25 GMT")
|
||||
|
||||
(string= (date->string dt2 :zone "JST") "2017-02-16 17:30:25 +09:00")
|
||||
(string= (date->string dt2 :zone "JST" :format :iso-8601) "2017-02-16T17:30:25+09:00")
|
||||
(string= (date->string dt2 :zone "JST" :format :asctime) "Thu Feb 16 17:30:25 +0900 2017")
|
||||
(string= (date->string dt2 :zone "JST" :format :rfc-822) "Thu, 16 Feb 2017 17:30:25 +0900")
|
||||
(string= (date->string dt2 :zone "JST" :format :rfc-850) "Thu, 16-Feb-2017 17:30:25 +0900"))))
|
||||
|
||||
(deftest special-dates ()
|
||||
(check
|
||||
(= (easter-day 2001) (ymd->date 2001 4 15))
|
||||
(= (easter-day 2002) (ymd->date 2002 3 31))
|
||||
(= (easter-day 2005) (ymd->date 2005 3 27))
|
||||
(= (easter-day 2011) (ymd->date 2011 4 24))
|
||||
|
||||
(= (vernal-equinox 2017)
|
||||
(ymd->date 2017 3 20 10 28 32.05221712589264d0))
|
||||
(= (summer-solstice 2017)
|
||||
(ymd->date 2017 6 21 4 23 43.49940687417984d0))
|
||||
(= (autumnal-equinox 2017)
|
||||
(ymd->date 2017 9 22 20 1 8.430179357528687D0))
|
||||
(= (winter-solstice 2017)
|
||||
(ymd->date 2017 12 21 16 27 51.39586955308914d0))
|
||||
(= (vernal-equinox 1959)
|
||||
(ymd->date 1959 3 21 8 55 7.991203665733337d0))
|
||||
(= (summer-solstice 1959)
|
||||
(ymd->date 1959 6 22 3 49 50.55352360010147d0))
|
||||
(= (autumnal-equinox 1959)
|
||||
(ymd->date 1959 9 23 19 8 29.363870322704315D0))
|
||||
(= (winter-solstice 1959)
|
||||
(ymd->date 1959 12 22 14 34 33.68946969509125d0))))
|
||||
|
||||
(deftest date-arith ()
|
||||
(check
|
||||
(= (date+ (ymd->date 2016 2 28) 1) (ymd->date 2016 2 29))
|
||||
(= (date+ (ymd->date 2016 2 28) 2) (ymd->date 2016 3 1))
|
||||
(= (date- (ymd->date 2016 3 1) 2) (ymd->date 2016 2 28))
|
||||
(= (date- (ymd->date 2016 3 1) 1) (ymd->date 2016 2 29))
|
||||
|
||||
(= (add-months (ymd->date 2016 2 29) 6) (ymd->date 2016 8 29))
|
||||
(= (add-months (ymd->date 2016 2 29) 6 :eom-rule :eom-normal) (ymd->date 2016 8 31))
|
||||
(= (add-months (ymd->date 2016 2 29) 6 :eom-rule :eom-no-leap-day) (ymd->date 2016 8 31))
|
||||
(= (add-months (ymd->date 2016 2 28) 6 :eom-rule :eom-normal) (ymd->date 2016 8 28))
|
||||
(= (add-months (ymd->date 2016 2 28) 6 :eom-rule :eom-no-leap-day) (ymd->date 2016 8 31))
|
||||
(= (add-months (ymd->date 2016 2 29) 12) (ymd->date 2017 2 28))
|
||||
(= (add-months (ymd->date 2016 2 29) 48) (ymd->date 2020 2 29))
|
||||
|
||||
(= (add-years (ymd->date 2016 2 29) 4) (add-months (ymd->date 2016 2 29) 48))
|
||||
|
||||
(= (add-months (ymd->date 2016 1 31) 1) (ymd->date 2016 2 29))
|
||||
(= (add-months (ymd->date 2016 1 31) 2) (ymd->date 2016 3 31))
|
||||
(= (add-months (ymd->date 2016 1 31) 3) (ymd->date 2016 4 30))
|
||||
|
||||
(= (add-months (ymd->date 2016 4 30) 1) (ymd->date 2016 5 30))
|
||||
(= (add-months (ymd->date 2016 4 30) 1 :eom-rule :eom-normal) (ymd->date 2016 5 31))
|
||||
(= (add-months (ymd->date 2016 4 30) 1 :eom-rule :eom-no-leap-day) (ymd->date 2016 5 31))
|
||||
(= (add-months (ymd->date 2016 4 30) 46 :eom-rule :eom-normal) (ymd->date 2020 2 29))
|
||||
(= (add-months (ymd->date 2016 4 30) 46 :eom-rule :eom-no-leap-day) (ymd->date 2020 2 28))
|
||||
|
||||
(= 0 (diff-days (ymd->date 2007 2 3 10 35 42) (ymd->date 2007 2 3 11 30 20)))
|
||||
(= 2 (diff-days (ymd->date 2008 2 28 10 35 42) (ymd->date 2008 3 1 11 30 20)))
|
||||
(= 366 (diff-days (ymd->date 2008 1 1 10 35 42) (ymd->date 2009 1 1 11 30 20)))
|
||||
(= 365 (diff-days (ymd->date 2007 1 1 10 35 42) (ymd->date 2008 1 1 11 30 20)))))
|
||||
|
||||
(deftest date-arith-360 ()
|
||||
(let ((test-cases
|
||||
;; Start date End Date Bond Basis 30E/360 30E/360 ISDA Act/360
|
||||
'(("2007-01-15" "2007-01-30" 0.041666667 0.041666667 0.041666667 0.041666667)
|
||||
("2007-01-15" "2007-02-15" 0.083333333 0.083333333 0.083333333 0.086111111)
|
||||
("2007-01-15" "2007-07-15" 0.5 0.5 0.5 0.502777778)
|
||||
("2007-09-30" "2008-03-31" 0.5 0.5 0.5 0.508333333)
|
||||
("2007-09-30" "2007-10-31" 0.083333333 0.083333333 0.083333333 0.086111111)
|
||||
("2007-09-30" "2008-09-30" 1 1 1 1.016666667)
|
||||
("2007-01-15" "2007-01-31" 0.044444444 0.041666667 0.041666667 0.044444444)
|
||||
("2007-01-31" "2007-02-28" 0.077777778 0.077777778 0.083333333 0.077777778)
|
||||
("2007-02-28" "2007-03-31" 0.091666667 0.088888889 0.083333333 0.086111111)
|
||||
("2006-08-31" "2007-02-28" 0.494444444 0.494444444 0.5 0.502777778)
|
||||
("2007-02-28" "2007-08-31" 0.508333333 0.505555556 0.5 0.511111111)
|
||||
("2007-02-14" "2007-02-28" 0.038888889 0.038888889 0.044444444 0.038888889)
|
||||
("2007-02-26" "2008-02-29" 1.008333333 1.008333333 1.011111111 1.022222222)
|
||||
("2008-02-29" "2009-02-28" 0.997222222 0.997222222 0.994444444 1.013888889)
|
||||
("2008-02-29" "2008-03-30" 0.086111111 0.086111111 0.083333333 0.083333333)
|
||||
("2008-02-29" "2008-03-31" 0.088888889 0.086111111 0.083333333 0.086111111)
|
||||
("2007-02-28" "2007-03-05" 0.019444444 0.019444444 0.013888889 0.013888889)
|
||||
("2007-10-31" "2007-11-28" 0.077777778 0.077777778 0.077777778 0.077777778)
|
||||
("2007-08-31" "2008-02-29" 0.497222222 0.497222222 0.5 0.505555556)
|
||||
("2008-02-29" "2008-08-31" 0.505555556 0.502777778 0.5 0.511111111)
|
||||
("2008-08-31" "2009-02-28" 0.494444444 0.494444444 0.494444444 0.502777778)
|
||||
("2009-02-28" "2009-08-31" 0.508333333 0.505555556 0.5 0.511111111)))
|
||||
(term-date (ymd->date 2009 2 28)))
|
||||
(labels ((a= (a b)
|
||||
(< (abs (- a b)) 0.000001)))
|
||||
(combine-results
|
||||
(loop for test in test-cases
|
||||
collect (let ((d1 (string->date (first test)))
|
||||
(d2 (string->date (second test)))
|
||||
(bond-basis (third test))
|
||||
(euro-basis (fourth test))
|
||||
(german (fifth test))
|
||||
(actual (sixth test)))
|
||||
(check
|
||||
(a= (diff-years d1 d2 :30a-360) bond-basis)
|
||||
(a= (diff-years d1 d2 :30e-360) euro-basis)
|
||||
(a= (diff-years d1 d2 :30e-360-isda :termination-date term-date) german)
|
||||
(a= (diff-years d1 d2 :act-360) actual))))))))
|
||||
|
||||
(deftest date-arith-act-act ()
|
||||
(let ((test-cases
|
||||
(list
|
||||
;; Start End Date F LC AFB ISDA ISMA
|
||||
(list "2003-11-01" "2004-05-01" 2 nil 182/366 (+ 61/365 121/366) (/ 182 (* 2 182)))
|
||||
(list "1999-02-01" "1999-07-01" 1 nil 150/365 150/365 (/ 150 (* 1 365)))
|
||||
(list "1999-07-01" "2000-07-01" 1 nil 1 (+ 184/365 182/366) (/ 366 (* 1 366)))
|
||||
(list "2002-08-15" "2003-07-15" 2 nil 334/365 334/365 (+ (/ 181 (* 2 181))
|
||||
(/ 153 (* 2 184))))
|
||||
(list "2003-07-15" "2004-01-15" 2 nil 184/365 (+ 170/365 14/366) (/ 184 (* 2 184)))
|
||||
(list "1999-07-30" "2000-01-30" 2 t 184/365 (+ 155/365 29/366) (/ 184 (* 2 184)))
|
||||
(list "2000-01-30" "2000-06-30" 2 t 152/366 152/366 (/ 152 (* 2 182)))
|
||||
(list "1999-11-30" "2000-04-30" 4 t 152/366 (+ 32/365 120/366) (+ (/ 91 (* 4 91))
|
||||
(/ 61 (* 4 92)))))))
|
||||
(combine-results
|
||||
(loop for test in test-cases
|
||||
collect (let ((d1 (string->date (first test)))
|
||||
(d2 (string->date (second test)))
|
||||
(freq (third test))
|
||||
(last-cpn (fourth test))
|
||||
(afb (fifth test))
|
||||
(isda (sixth test))
|
||||
(isma (seventh test)))
|
||||
(check
|
||||
(= (diff-years d1 d2 :act-act-afb) afb)
|
||||
(= (diff-years d1 d2 :act-act) isda)
|
||||
(= (diff-years d1 d2 :act-act-isma :frequency freq :is-last-coupon last-cpn) isma)))))))
|
||||
|
||||
(deftest bus-date-arith ()
|
||||
(let ((cal (make-calendar :jpy :base-year 2017)))
|
||||
(check
|
||||
(= 245 (workday-number (ymd->date 2016 12 31) cal))
|
||||
(= 20 (workday-number (ymd->date 2017 2 1) cal))
|
||||
(= 247 (workday-number (ymd->date 2017 12 31) cal))
|
||||
|
||||
(date= (ymd->date 2017 1 4) (next-workday (ymd->date 2016 12 31) cal))
|
||||
(date= (ymd->date 2016 5 2) (next-workday (ymd->date 2016 4 28) cal))
|
||||
(date= (ymd->date 2017 5 8) (next-workday (ymd->date 2017 5 2) cal))
|
||||
|
||||
(date= (ymd->date 2016 12 30) (prev-workday (ymd->date 2017 1 4) cal))
|
||||
(date= (ymd->date 2017 4 28) (prev-workday (ymd->date 2017 5 1) cal))
|
||||
(date= (ymd->date 2017 5 2) (prev-workday (ymd->date 2017 5 8) cal))
|
||||
|
||||
(date= (ymd->date 2018 1 4) (add-workdays (ymd->date 2017 1 1) cal 248))
|
||||
(date= (ymd->date 2017 2 1) (add-workdays (ymd->date 2017 1 1) cal 20))
|
||||
|
||||
(= 20 (diff-workdays (ymd->date 2017 1 1) (ymd->date 2017 2 1) cal))
|
||||
(= 247 (diff-workdays (ymd->date 2017 1 1) (ymd->date 2017 12 31) cal))
|
||||
(= 247 (diff-workdays (ymd->date 2018 1 4) (ymd->date 2017 1 4) cal))
|
||||
|
||||
(date= (ymd->date 2016 5 2) (first-workday-of-month (ymd->date 2016 5 10) cal))
|
||||
(date= (ymd->date 2017 4 28) (last-workday-of-month (ymd->date 2017 4 1) cal))
|
||||
(date= (ymd->date 2017 4 28) (last-workday-of-prev-month (ymd->date 2017 5 10) cal))
|
||||
|
||||
(date= (ymd->date 2016 5 2) (adjust-date (ymd->date 2016 4 30) cal :following))
|
||||
(date= (ymd->date 2016 4 28) (adjust-date (ymd->date 2016 4 30) cal :modified-following))
|
||||
(date= (ymd->date 2016 4 28) (adjust-date (ymd->date 2016 4 30 1) cal :preceding)))))
|
||||
|
||||
(deftest schedule-generation ()
|
||||
(let ((target-cal (make-calendar :target :base-year 2002))
|
||||
(japan-cal (make-calendar :japan :base-year 2009))
|
||||
(bond-cal (make-calendar :us-bond :base-year 1996)))
|
||||
(check
|
||||
;; Adjusted maturity date with month-end roll
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 2009 9 30) (ymd->date 2012 6 15)
|
||||
6 japan-cal :rule :normal-front
|
||||
:roll-convention :following
|
||||
:maturity-roll :following
|
||||
:eom-rule :eom-normal))
|
||||
(list "2009-09-30" "2010-03-31" "2010-09-30" "2011-03-31" "2011-09-30"
|
||||
"2012-03-30" "2012-06-29"))
|
||||
;; same as above with unadjusted maturity
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 2009 9 30) (ymd->date 2012 6 15)
|
||||
6 japan-cal :rule :normal-front
|
||||
:roll-convention :following
|
||||
:maturity-roll nil
|
||||
:eom-rule :eom-normal))
|
||||
(list "2009-09-30" "2010-03-31" "2010-09-30" "2011-03-31" "2011-09-30"
|
||||
"2012-03-30" "2012-06-15"))
|
||||
;; Coupon date of 2015/3/31 (after EOM adjustment) is dropped because it is beyond maturity
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 2013 3 28) (ymd->date 2015 3 30)
|
||||
12 target-cal :rule :normal-front
|
||||
:roll-convention nil
|
||||
:maturity-roll nil
|
||||
:eom-rule :eom-normal))
|
||||
(list "2013-03-28" "2014-03-31" "2015-03-30"))
|
||||
;; Coupon date of 2015/3/31 (after EOM adjustment) is dropped because it is equal to maturity
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 2013 3 28) (ymd->date 2015 3 31)
|
||||
12 target-cal :rule :normal-front
|
||||
:roll-convention nil
|
||||
:maturity-roll nil
|
||||
:eom-rule :eom-normal))
|
||||
(list "2013-03-28" "2014-03-31" "2015-03-31"))
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 1996 8 31) (ymd->date 1997 9 15)
|
||||
6 bond-cal :rule :normal-front
|
||||
:roll-convention nil
|
||||
:maturity-roll nil
|
||||
:eom-rule :eom-normal))
|
||||
(list "1996-08-31" "1997-02-28" "1997-08-31" "1997-09-15"))
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 1996 8 22) (ymd->date 1997 8 31)
|
||||
6 bond-cal :rule :normal-back
|
||||
:roll-convention nil
|
||||
:maturity-roll nil
|
||||
:eom-rule :eom-normal))
|
||||
(list "1996-08-22" "1996-08-31" "1997-02-28" "1997-08-31"))
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 1996 8 22) (ymd->date 1997 8 31)
|
||||
6 bond-cal :rule :normal-back
|
||||
:roll-convention :following
|
||||
:maturity-roll :following
|
||||
:eom-rule :eom-normal))
|
||||
(list "1996-08-22" "1996-08-30" "1997-02-28" "1997-08-29"))
|
||||
(equal (mapcar #'date->string (generate-schedule (ymd->date 2016 12 12) (ymd->date 2021 12 12)
|
||||
3 japan-cal :rule :cds-dates
|
||||
:roll-convention :modified-following
|
||||
:maturity-roll nil
|
||||
:eom-rule nil))
|
||||
(list "2016-09-20" "2016-12-20" "2017-03-21" "2017-06-20" "2017-09-20" "2017-12-20"
|
||||
"2018-03-20" "2018-06-20" "2018-09-20" "2018-12-20" "2019-03-20" "2019-06-20"
|
||||
"2019-09-20" "2019-12-20" "2020-03-23" "2020-06-22" "2020-09-23" "2020-12-21"
|
||||
"2021-03-22" "2021-06-21" "2021-09-21" "2021-12-20")))))
|
||||
98
test/test-hols.lisp
Normal file
98
test/test-hols.lisp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
;;; Copyright (c) 2017, Sudhir Shenoy. All rights reserved.
|
||||
|
||||
;;; Redistribution and use in source and binary forms, with or without
|
||||
;;; modification, are permitted provided that the following conditions
|
||||
;;; are met:
|
||||
|
||||
;;; * Redistributions of source code must retain the above copyright
|
||||
;;; notice, this list of conditions and the following disclaimer.
|
||||
|
||||
;;; * Redistributions in binary form must reproduce the above
|
||||
;;; copyright notice, this list of conditions and the following
|
||||
;;; disclaimer in the documentation and/or other materials
|
||||
;;; provided with the distribution.
|
||||
|
||||
;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
|
||||
;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
(in-package :cl-dates-test)
|
||||
|
||||
(defparameter +holiday-tests+
|
||||
'(;; US settlement holidays
|
||||
(:usd (2004 2005) ("1 January 2004" "19 January 2004" "16 February 2004" "31 May 2004"
|
||||
"5 July 2004" "6 September 2004" "11 October 2004" "11 November 2004"
|
||||
"25 November 2004" "24 December 2004" "31 December 2004"
|
||||
"17 January 2005" "21 February 2005" "30 May 2005" "4 July 2005"
|
||||
"5 September 2005" "10 October 2005" "11 November 2005"
|
||||
"24 November 2005" "26 December 2005"))
|
||||
;; US settlement - before Uniform Monday Holiday Act
|
||||
(:usd (1961 1961) ("2 January 1961" "22 February 1961" "30 May 1961" "4 July 1961"
|
||||
"4 September 1961" "10 November 1961" "23 November 1961"
|
||||
"25 December 1961"))
|
||||
;; US Bond market
|
||||
(:ust (2004 2004) ("1 January 2004" "19 January 2004" "16 February 2004" "9 April 2004"
|
||||
"31 May 2004" "5 July 2004" "6 September 2004" "11 October 2004"
|
||||
"11 November 2004" "25 November 2004" "24 December 2004"))
|
||||
;; NY Stock exchange
|
||||
(:nyse (2004 2006) ("1 January 2004" "19 January 2004" "16 February 2004" "9 April 2004"
|
||||
"31 May 2004" "11 June 2004" "5 July 2004" "6 September 2004"
|
||||
"25 November 2004" "24 December 2004"
|
||||
"17 January 2005" "21 February 2005" "25 March 2005" "30 May 2005"
|
||||
"4 July 2005" "5 September 2005" "24 November 2005" "26 December 2005"
|
||||
"2 January 2006" "16 January 2006" "20 February 2006" "14 April 2006"
|
||||
"29 May 2006" "4 July 2006" "4 September 2006" "23 November 2006"
|
||||
"25 December 2006"))
|
||||
;; TARGET
|
||||
(:target (1999 2002) ("1 January 1999" "31 December 1999"
|
||||
"21 April 2000" "24 April 2000" "1 May 2000" "25 December 2000"
|
||||
"26 December 2000"
|
||||
"1 January 2001" "13 April 2001" "16 April 2001" "1 May 2001"
|
||||
"25 December 2001" "26 December 2001" "31 December 2001"
|
||||
"1 January 2002" "29 March 2002" "1 April 2002" "1 May 2002"
|
||||
"25 December 2002" "26 December 2002"))
|
||||
(:target (2003 2006) ("1 January 2003" "18 April 2003" "21 April 2003" "1 May 2003"
|
||||
"25 December 2003" "26 December 2003"
|
||||
"1 January 2004" "9 April 2004" "12 April 2004"
|
||||
"25 March 2005" "28 March 2005" "26 December 2005"
|
||||
"14 April 2006" "17 April 2006" "1 May 2006" "25 December 2006"
|
||||
"26 December 2006"))
|
||||
;; EUREX
|
||||
(:eurex (2003 2004) ("1 January 2003" "18 April 2003" "21 April 2003" "1 May 2003"
|
||||
"24 December 2003" "25 December 2003" "26 December 2003" "31 December 2003"
|
||||
"1 January 2004" "9 April 2004" "12 April 2004" "24 December 2004"
|
||||
"31 December 2004"))
|
||||
;; UK
|
||||
(:gbp (2004 2007) ("1 January 2004" "9 April 2004" "12 April 2004" "3 May 2004" "31 May 2004"
|
||||
"30 August 2004" "27 December 2004" "28 December 2004"
|
||||
"3 January 2005" "25 March 2005" "28 March 2005" "2 May 2005" "30 May 2005"
|
||||
"29 August 2005" "26 December 2005" "27 December 2005"
|
||||
"2 January 2006" "14 April 2006" "17 April 2006" "1 May 2006" "29 May 2006"
|
||||
"28 August 2006" "25 December 2006" "26 December 2006"
|
||||
"1 January 2007" "6 April 2007" "9 April 2007" "7 May 2007" "28 May 2007"
|
||||
"27 August 2007" "25 December 2007" "26 December 2007"))))
|
||||
|
||||
(deftest holiday-tests ()
|
||||
(combine-results
|
||||
(loop for test-case in +holiday-tests+
|
||||
collect (destructuring-bind (centre year-range dates) test-case
|
||||
(setf dates (mapcar #'jday-number (mapcar #'string->date dates)))
|
||||
(let* ((from-year (car year-range))
|
||||
(start-range (ymd->date from-year 1 1))
|
||||
(end-range (ymd->date (cadr year-range) 12 31))
|
||||
(cal (make-calendar centre :base-year from-year))
|
||||
(hols (sort (loop for dt being the
|
||||
hash-keys in (cl-dates::holidays cal)
|
||||
when (date<= start-range dt end-range)
|
||||
collect dt)
|
||||
#'date<)))
|
||||
(check
|
||||
(equal hols dates)))))))
|
||||
93
test/test-main.lisp
Normal file
93
test/test-main.lisp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
;;; Copyright (c) 2017, Sudhir Shenoy. All rights reserved.
|
||||
|
||||
;;; Redistribution and use in source and binary forms, with or without
|
||||
;;; modification, are permitted provided that the following conditions
|
||||
;;; are met:
|
||||
|
||||
;;; * Redistributions of source code must retain the above copyright
|
||||
;;; notice, this list of conditions and the following disclaimer.
|
||||
|
||||
;;; * Redistributions in binary form must reproduce the above
|
||||
;;; copyright notice, this list of conditions and the following
|
||||
;;; disclaimer in the documentation and/or other materials
|
||||
;;; provided with the distribution.
|
||||
|
||||
;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
|
||||
;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
(in-package :cl-user)
|
||||
|
||||
(defpackage :cl-dates-test
|
||||
(:use :common-lisp :cl-dates)
|
||||
(:export :run-all-tests))
|
||||
|
||||
(in-package :cl-dates-test)
|
||||
|
||||
;;;
|
||||
;;; Peter Siebel's test framework from Practical Common Lisp with
|
||||
;;; slight modifications
|
||||
;;;
|
||||
(defvar *test-name* nil)
|
||||
(defvar *verbose-results* nil)
|
||||
(defvar *total-tests* 0)
|
||||
(defvar *failed-tests* 0)
|
||||
|
||||
(defmacro deftest (name parameters &body body)
|
||||
"Define a test function. Within a test function we can call
|
||||
other test functions or use 'check' to run individual test
|
||||
cases."
|
||||
`(defun ,name ,parameters
|
||||
(let ((*test-name* (append *test-name* (list ',name))))
|
||||
(format t "~a ... from test #~d~%" *test-name* (1+ *total-tests*))
|
||||
,@body)))
|
||||
|
||||
(defmacro check (&body forms)
|
||||
"Run each expression in 'forms' as a test case."
|
||||
`(combine-results
|
||||
,@(loop for f in forms collect `(report-result ,f ',f))))
|
||||
|
||||
(defun combine-results (&rest exprs)
|
||||
"Combine the results (as booleans) of evaluating 'exprs' in order."
|
||||
(every #'identity exprs))
|
||||
|
||||
(defun report-result (result form)
|
||||
"Report the results of a single test case. Called by 'check'."
|
||||
(incf *total-tests*)
|
||||
(when (not result)
|
||||
(incf *failed-tests*))
|
||||
(if *verbose-results*
|
||||
(format t "#~d: ~:[FAIL~;pass~] ... ~a: ~a~%" *total-tests* result *test-name* form)
|
||||
(when (not result)
|
||||
(format t "#~d: FAIL ... ~a: ~a~%" *total-tests* *test-name* form)))
|
||||
result)
|
||||
|
||||
(defun run-all-tests (&key (verbose nil))
|
||||
(let* ((*total-tests* 0)
|
||||
(*failed-tests* 0)
|
||||
(*verbose-results* verbose)
|
||||
(status (combine-results
|
||||
(julian)
|
||||
(misc-fns)
|
||||
(special-dates)
|
||||
(date-arith)
|
||||
(date-arith-360)
|
||||
(date-arith-act-act)
|
||||
(print-fns)
|
||||
(parse-dates)
|
||||
(holiday-tests)
|
||||
(bus-date-arith)
|
||||
(schedule-generation))))
|
||||
(unless (zerop *total-tests*)
|
||||
(format t "~d tests executed - ~d passed (~,2f%)~%"
|
||||
*total-tests* (- *total-tests* *failed-tests*)
|
||||
(/ (* 100 (- *total-tests* *failed-tests*)) *total-tests*)))
|
||||
status))
|
||||
206
test/test-parse-date.lisp
Normal file
206
test/test-parse-date.lisp
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
;;; Copyright (c) 2017, Sudhir Shenoy. All rights reserved.
|
||||
|
||||
;;; Redistribution and use in source and binary forms, with or without
|
||||
;;; modification, are permitted provided that the following conditions
|
||||
;;; are met:
|
||||
|
||||
;;; * Redistributions of source code must retain the above copyright
|
||||
;;; notice, this list of conditions and the following disclaimer.
|
||||
|
||||
;;; * Redistributions in binary form must reproduce the above
|
||||
;;; copyright notice, this list of conditions and the following
|
||||
;;; disclaimer in the documentation and/or other materials
|
||||
;;; provided with the distribution.
|
||||
|
||||
;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
|
||||
;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
(in-package :cl-dates-test)
|
||||
|
||||
;; Rounding errors in fractional seconds when changing timezones require
|
||||
;; testing for approximate equality in some test cases
|
||||
(defparameter +max-error+ 1/1000000)
|
||||
(defun a= (a b)
|
||||
(< (abs (- a b)) +max-error+))
|
||||
|
||||
(deftest parse-dates ()
|
||||
(let ((dt (ymd->date 2003 9 25 1 36 28)))
|
||||
(check
|
||||
;; Fully specified date with time and timezone
|
||||
(= (string->date "Thu Sep 25 10:36:28 JST 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(null (string->date "Wed Sep 25 10:36:28 JST 2003" :reference-date dt)) ; day of week doesn't match date
|
||||
(= (string->date "2003 10:36:28 JST 25 Sep Thu" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Thu, 25 Sep 2003 10:36:28 JST" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Thu, 25 Sep 2003 10:36:28 +0900" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003-09-25T10:49:41-03:00" :reference-date dt) (ymd->date 2003 9 25 13 49 41))
|
||||
(a= (string->date "2003-09-25T10:49:41.5-03:00" :reference-date dt) (ymd->date 2003 9 25 13 49 41.5))
|
||||
(= (string->date "20030925T10:49:41-03:00" :reference-date dt) (ymd->date 2003 9 25 13 49 41))
|
||||
(a= (string->date "20030925T10:49:41.5-03:00" :reference-date dt) (ymd->date 2003 9 25 13 49 41.5))
|
||||
|
||||
;; Partially specified dates (alphanumeric)
|
||||
(= (string->date "Thu Sep 25 10:36:28 2003" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "Thu Sep 25 10:36:28" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "Thu Sep 10:36:28" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "Thu 10:36:28" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "Sep 10:36:28" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "10:36:28" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "10:36" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "Thu Sep 25 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Sep 25 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Sep 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Sep" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003-09-25T10:49:41" :reference-date dt) (ymd->date 2003 9 25 10 49 41))
|
||||
(= (string->date "2003-09-25T10:49" :reference-date dt) (ymd->date 2003 9 25 10 49 28))
|
||||
(= (string->date "2003-09-25T10" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "2003-09-25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "20030925T104941" :reference-date dt) (ymd->date 2003 9 25 10 49 41))
|
||||
(= (string->date "20030925T1049" :reference-date dt) (ymd->date 2003 9 25 10 49 28))
|
||||
(= (string->date "20030925T10" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "20030925T10:49:41" :reference-date dt) (ymd->date 2003 9 25 10 49 41))
|
||||
(= (string->date "20030925T10:49" :reference-date dt) (ymd->date 2003 9 25 10 49 28))
|
||||
(= (string->date "20030925T10" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "20030925" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
|
||||
;; Partially specified (numeric with possible alphabetic month name
|
||||
(= (string->date "19970902090807" :reference-date dt) (ymd->date 1997 9 2 9 8 7))
|
||||
(= (string->date "199709020908" :reference-date dt) (ymd->date 1997 9 2 9 8 28))
|
||||
(= (string->date "2003-Sep-25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25-Sep-2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Sep-25-2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "09-25-2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28)) ; no ambiguity because 25 is a day
|
||||
(= (string->date "25-09-2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28)) ; no ambiguity because 25 is a day
|
||||
(= (string->date "10-09-2003" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10-09-2003" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "10-09-03" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "10-09-03" :precedence :ymd :reference-date dt)
|
||||
(ymd->date 2010 9 3 1 36 28)) ; explicitly yy/mm/dd
|
||||
(= (string->date "2003.09.25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003.Sep.25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25.Sep.2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "09.25.2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25.09.2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003/09/25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003/Sep/25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25/Sep/2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "09/25/2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25/09/2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "10.09.2003" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10.09.2003" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "10.09.03" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10.09.03" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "10/09/2003" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10/09/2003" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "10/09/03" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10/09/03" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(null (string->date "2003/25/Sep" :reference-date dt)) ; invalid - yy/dd/MMM
|
||||
(= (string->date "2003 09 25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003 Sep 25" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "2003 25 Sep" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25 Sep 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Sep 25 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "09 25 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "25 09 2003" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "10 09 2003" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10 09 2003" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "10 09 03" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 10 1 36 28)) ; explicitly dd/mm/yy
|
||||
(= (string->date "10 09 03" :precedence :mdy :reference-date dt)
|
||||
(ymd->date 2003 10 9 1 36 28)) ; explicitly mm/dd/yy
|
||||
(= (string->date "03 25 Sep" :reference-date dt)
|
||||
(ymd->date 2003 9 25 1 36 28)) ; default is yy/mm/dd
|
||||
(= (string->date "25 03 Sep" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2003 9 25 1 36 28)) ; explicitly day before year
|
||||
|
||||
;; Assorted time formats
|
||||
(a= (string->date "10h16m38.5s" :reference-date dt) (ymd->date 2003 9 25 10 16 38.5))
|
||||
(= (string->date "10h16m38s" :reference-date dt) (ymd->date 2003 9 25 10 16 38))
|
||||
(a= (string->date "10h16m" :reference-date dt) (ymd->date 2003 9 25 10 16 28))
|
||||
(= (string->date "10h" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(a= (string->date "10 h 16" :reference-date dt) (ymd->date 2003 9 25 10 16 28))
|
||||
(= (string->date "10h am" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "10h pm" :reference-date dt) (ymd->date 2003 9 25 22 36 28))
|
||||
(= (string->date "10 am" :reference-date dt) (ymd->date 2003 9 25 10 36 28))
|
||||
(= (string->date "10 pm" :reference-date dt) (ymd->date 2003 9 25 22 36 28))
|
||||
(= (string->date "10:00 am" :reference-date dt) (ymd->date 2003 9 25 10 0 28))
|
||||
(= (string->date "10:00 pm" :reference-date dt) (ymd->date 2003 9 25 22 0 28))
|
||||
(= (string->date "10:00am" :reference-date dt) (ymd->date 2003 9 25 10 0 28))
|
||||
(= (string->date "10:00pm" :reference-date dt) (ymd->date 2003 9 25 22 0 28))
|
||||
(= (string->date "10:00a.m." :reference-date dt) (ymd->date 2003 9 25 10 0 28))
|
||||
(= (string->date "10:00p.m." :reference-date dt) (ymd->date 2003 9 25 22 0 28))
|
||||
(= (string->date "10:00a.m" :reference-date dt) (ymd->date 2003 9 25 10 0 28))
|
||||
(= (string->date "10:00p.m" :reference-date dt) (ymd->date 2003 9 25 22 0 28))
|
||||
|
||||
;; relative dates etc
|
||||
(= (string->date "Sep 03" :reference-date dt) (ymd->date 2003 9 3 1 36 28))
|
||||
(= (string->date "Sep of 03" :reference-date dt) (ymd->date 2003 9 25 1 36 28))
|
||||
(= (string->date "Wed" :reference-date dt) (ymd->date 2003 9 24 1 36 28))
|
||||
(= (string->date "Wednesday" :reference-date dt) (ymd->date 2003 9 24 1 36 28))
|
||||
(= (string->date "last Wednesday" :reference-date dt) (ymd->date 2003 9 24 1 36 28))
|
||||
(= (string->date "next Wednesday" :reference-date dt) (ymd->date 2003 10 1 1 36 28))
|
||||
(= (string->date "October" :reference-date dt) (ymd->date 2003 10 25 1 36 28))
|
||||
(= (string->date "31-Dec-00" :precedence :dmy :reference-date dt)
|
||||
(ymd->date 2000 12 31 1 36 28))
|
||||
|
||||
;; Random verbiage / unusual formats
|
||||
(= (string->date "The date is the 25th of September of 2003, exactly at 10:49:41 with time zone -03:00"
|
||||
:reference-date dt) (ymd->date 2003 9 25 13 49 41))
|
||||
(null (string->date "Today is the 25th of September of 2003, exactly at 10:49:41 with time zone -03:00"
|
||||
:reference-date dt)) ; 'today' is assumed to be a date spec so a duplicate date is detected
|
||||
(= (string->date " July 4 , 1976 12:01:02 am " :reference-date dt)
|
||||
(ymd->date 1976 7 4 0 1 2))
|
||||
(= (string->date "today 12:35" :reference-date dt) (ymd->date 2003 9 25 12 35 28))
|
||||
(= (string->date "today 12:35 JST" :reference-date dt) (ymd->date 2003 9 25 3 35 28))
|
||||
(= (string->date "tomorrow 12:35" :reference-date dt) (ymd->date 2003 9 26 12 35 28))
|
||||
(= (string->date "yesterday 12:35 am JST" :reference-date dt) (ymd->date 2003 9 23 15 35 28)) ; date is 2 days prior in UTC
|
||||
(= (string->date "Wed Jul 10, '96" :reference-date dt) (ymd->date 1996 7 10 1 36 28))
|
||||
(a= (string->date "1996.07.10 AD at 15:08:56 PDT" :reference-date dt) (ymd->date 1996 7 10 22 8 56))
|
||||
(= (string->date "1996.07.10 AD at 12:08 PM" :reference-date dt) (ymd->date 1996 7 10 12 8 28))
|
||||
(= (string->date "Saturday, April 12, 1952 AD 3:30:42pm PST" :reference-date dt) (ymd->date 1952 4 12 23 30 42))
|
||||
(= (string->date "November 5, 1994, 8:15:30 am EST" :reference-date dt) (ymd->date 1994 11 5 13 15 30))
|
||||
(= (string->date "1994-11-05T08:15:30-05:00" :reference-date dt) (ymd->date 1994 11 5 13 15 30))
|
||||
(= (string->date "1994-11-05T08:15:30Z" :reference-date dt) (ymd->date 1994 11 5 8 15 30))
|
||||
(= (string->date "0:01:02" :reference-date dt) (ymd->date 2003 9 25 0 1 2))
|
||||
(= (string->date "12h 01m02s am" :reference-date dt) (ymd->date 2003 9 25 0 1 2))
|
||||
(= (string->date "0:01:02 on July 4, 1976" :reference-date dt) (ymd->date 1976 7 4 0 1 2))
|
||||
(null (string->date "July 4, 1976 pm 12:01:02" :reference-date dt)) ; am/pm must come after time spec
|
||||
(= (string->date "July 4, 4pm 4:01:02" :reference-date dt)
|
||||
(ymd->date 2003 7 4 4 1 2)) ; 4pm overridden by 4:01:02
|
||||
(= (string->date "July 4, 4pm" :reference-date dt) (ymd->date 2003 7 4 16 36 28)) ; this is ok
|
||||
(a= (string->date "04.04.95 00:22" :reference-date dt) (ymd->date 1995 4 4 0 22 28))
|
||||
(= (string->date "950404 122212" :reference-date dt) (ymd->date 1995 4 4 12 22 12))
|
||||
(= (string->date "0:00 PM, PST" :reference-date dt) (ymd->date 2003 9 25 20 0 28))
|
||||
(= (string->date "12:08 PM" :reference-date dt) (ymd->date 2003 9 25 12 8 28))
|
||||
(= (string->date "5:50 A.M on June 13, 1990" :reference-date dt) (ymd->date 1990 6 13 5 50 28))
|
||||
(= (string->date "01h02m03" :reference-date dt) (ymd->date 2003 9 25 1 2 3))
|
||||
(= (string->date "01h02" :reference-date dt) (ymd->date 2003 9 25 1 2 28))
|
||||
(= (string->date "01h02s" :reference-date dt) (ymd->date 2003 9 25 1 36 2))
|
||||
(= (string->date "01m02" :reference-date dt) (ymd->date 2003 9 25 1 1 2))
|
||||
(a= (string->date "01m02h" :reference-date dt) (ymd->date 2003 9 25 2 1 28))
|
||||
(= (string->date "2004 10 April 11h30m" :reference-date dt) (ymd->date 2004 4 10 11 30 28))
|
||||
;; The next one works coincidentally because Japanese uses a y/m/d format by default.
|
||||
;; However, it demonstrates that as long as date components are present, the presence
|
||||
;; of extraneous characters does not matter
|
||||
(= (string->date "2004年8月9日 17:30:22" :reference-date dt) (ymd->date 2004 8 9 17 30 22)))))
|
||||
Loading…
Add table
Add a link
Reference in a new issue