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:
1309368600000
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?!
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.