Last active
August 29, 2015 14:14
-
-
Save dyba/4c13973411343845bd0c to your computer and use it in GitHub Desktop.
Excel's DAYS360 in Clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns days360.core | |
(:require [clj-time.core :as t] | |
[clj-time.format :as f] | |
[clj-time.predicates :as p] | |
[clj-time.periodic :as per])) | |
;; It works! Now to prettify it... | |
(defn days360 | |
"Calculates the number of days between a start-date and end-date according to | |
a 360-day year." | |
[start-date end-date] | |
(let [[sd ed] (let [d1 (f/parse start-date) | |
d2 (f/parse end-date)] | |
(if (t/after? d1 d2) [d2 d1] [d1 d2])) | |
[sdy sdm sdd] [(t/year sd) (t/month sd) (t/day sd)] | |
[edy edm edd] [(t/year ed) (t/month ed) (t/day ed)] | |
sdd (if (p/last-day-of-month? sd) | |
30 | |
sdd) | |
[edm edd] (if (and (p/last-day-of-month? ed) | |
(if (p/february? sd) | |
(< (t/day sd) 29) | |
(< (t/day sd) 30))) | |
[(+ 1 (t/month ed)) 1] | |
[(t/month ed) (min 30 (t/day ed))])] | |
(+ (* 360 (- edy sdy)) | |
(* 30 (- edm sdm)) | |
(- edd sdd)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns days360.core-test | |
(:require [clojure.test :refer :all] | |
[days360.core :refer :all])) | |
(deftest calculating-days-between-dates | |
(testing "interval-in-days" | |
(testing "when passing the :as :360-day-yr option" | |
(testing "a starting date on the last day of the month is treated as the 30th" | |
(is (= (days360 "2008-01-30" "2008-02-01") 1)) | |
(is (= (days360 "2015-01-31" "2015-02-01") 1)) | |
(is (= (days360 "1996-02-29" "1996-03-01") 1)) | |
(is (= (days360 "1993-02-28" "1993-03-01") 1)) | |
(is (= (days360 "2008-01-30" "2008-01-31") 0)) | |
(is (= (days360 "2008-02-29" "2008-08-31") 180)) | |
(is (= (days360 "2008-02-29" "2008-03-30") 30)) | |
(is (= (days360 "2008-02-29" "2008-03-31") 30)) | |
(is (= (days360 "2008-02-28" "2008-03-31") 33)) | |
(is (= (days360 "2008-01-01" "2008-12-31") 360)) | |
(is (= (days360 "2008-01-01" "2008-02-01") 30)) | |
(is (= (days360 "2015-01-01" "2015-01-31") 30)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment