Search code examples
javaclojureclj-time

How do I add days to a date in Clojure


I have looked at the following question: How to add days to current date in clojure.

However I am very new to Clojure and I am getting stuck on the following scenario I am getting the timestamp in string format. So I am parsing it using the following:

(.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date)

Which gives me a result that looks like this:

#inst "2015-02-13T00:20:00.000-00:00"

How do I add say 90 days to this and then convert it back to string format? I tried this based on the above link:

(java.util.Date. (+ (* 7 86400 1000) 
                    (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date)))

Which gave me the following error:

ClassCastException java.util.Date cannot be cast to java.lang.Number  clojure.lang.Numbers.add

Solution

  • parse returns a java.util.Date, the error you are seeing is telling you that you can't cast a Date to a Number. You can use getTime to get the milliseconds of a Date:

    (java.util.Date. (+ (* 7 86400 1000)
                     (.getTime (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date))))
    

    This potentially adds 7 days to the date. If you want to potentially add 90 days you need to replace the 7 with 90, like this: (* 90 86400 1000).

    You can also use java.util.Calendar:

    (let [cal (Calendar/getInstance)
          d (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date)]
      (doto cal
        (.setTime d)
        (.add Calendar/DATE 90)
        (.getTime)))
    

    Or better yet, clj-time:

    (require '[clj-time.core :as t])
    (require '[clj-time.format :as f])
    
    (t/plus (f/parse (f/formatters :year-month-day) date)
            (t/days 90))