A few weeks ago, I found myself needing to manipulate dates in various ways (things like "a list of the next 50 weekdays", or "how many working days between now and July 1, 2012"), and went searching for a Clojure-ish solution.
My first attempt was an ugly mess of imperative code written in Clojure (which worked but left me feeling pretty dirty inside — see #2), but my second, centering around
iterate and Joda Time, worked out quite well, and I thought I'd share.
Now, in advance, I'm still learning Clojure, so I'm sure the more experienced among you will find plenty of opportunities to mock, but getting this working was a serious aha! moment for me, and helped me grok several important functional programming principles.
First, the code:
I chose the
org.joda.time.LocalDate class as a starting point because I didn't need anything more than day precision, though something similar could be created using
org.joda.time.DateTime objects, too.
From these starting points, you can do all sorts of cool things. Want to get a list of the next 50 weekend days? Define a function to use in a call to
filter, and then
take the first 50 that come back, like this:
It's also trivial to get the "next X" date (e.g., "next Friday the 13th", etc.) by creating the appropriate filter function, applying it to the date sequence, and then applying
first to pick off only the first element that's returned. Since the sequence is lazy, the fact that it could generate an infinite list of dates doesn't mean, that using it only for the first is inefficient.
Like I said before, this isn't rocket science, but it's a nice way to see how infinite lazy sequences can be used to solve problems that are only inelegantly implementable with traditional imperative approaches.