Clojure: clj-time - Formatting a date / timestamp with day suffixes e.g. 1st, 2nd, 3rd
I've been using the clj-time library recently - a Clojure wrapper around Joda Time - and one thing I wanted to do is format a date with day suffixes e.g. 1st, 2nd, 3rd.
I started with the following timestamp:
The first step was to convert that into a DateTime object like so:
user> (require '[clj-time.coerce :as c]) user> (c/from-long 1309368600000) #<DateTime 2011-06-29T17:30:00.000Z>
I wanted to output that date in the following format:
29th June 2011
We can get quite close by using a custom time formatter:
user> (require '[clj-time.format :as f]) nil user> (f/unparse (f/formatter "d MMMM yyyy") (c/from-long 1309368600000)) "29 June 2011"
Unfortunately I couldn't find anywhere in the documentation explaining how to get the elusive 'th' or 'st' to print. I was hoping for something similar to PHP date formatting:
Eventually I came across a Stack Overflow post about Joda Time suggesting that you can't actually format a day in the way I was hoping to.
So I now have the following function to do it for me:
(defn day-suffix [day] (let [stripped-day (if (< day 20) day (mod day 10))] (cond (= stripped-day 1) "st" (= stripped-day 2) "nd" (= stripped-day 3) "rd" :else "th")))
and the code to get the date in my favoured format looks like this:
user> (def my-time (c/from-long 1309368600000)) #'user/my-time user> (def day (read-string (f/unparse (f/formatter "d") my-time))) #'user/day user> (str day (day-suffix day) " " (f/unparse (f/formatter "MMMM yyyy") my-time)) "29th June 2011"
I'm assuming there's a better way but what is it?!