John Biesnecker

I am a mobile/web product designer living in Shanghai.

Visit me on LinkedIn or Github.

15 Jan 2012

Infinite lazy date sequences with Clojure and Joda Time


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.




If you liked this post, you might also like to read about some of the projects that I'm currently working on.


I may be one of the last people in the world that likes email, so please drop me a line.


Go Cardinals!