Today, being Halloween Oct 31, one of our automated unit tests started failing. The failure was interesting because that test had been around for a few months and no changes had been made to that area of code or the test for a long time. So digging into it, I found the following exception print out:
org.joda.time.IllegalFieldValueException: Value 31 for dayOfMonth must be in the range [1,30]
at org.joda.time.field.FieldUtils.verifyValueBounds(FieldUtils.java:217) at org.joda.time.field.PreciseDurationDateTimeField.set(PreciseDurationDateTimeField.java:78) at org.joda.time.chrono.ZonedChronology$ZonedDateTimeField.set(ZonedChronology.java:466) at org.joda.time.DateMidnight.withDayOfMonth(DateMidnight.java:1063)
But how can that be? October surely has 31 days. Otherwise there would be millions of angry and sugar deprived kids.
After some more debugging and more unit tests, I discovered that org.joda.time.DateMidnight was 1-based for its month value. And we are using net.sourceforge.jdatepicker.JDatePicker for a Swing GUI. The backing model object for JDatePicker is 0-based for its month value. So we were off by 1 month in our translation and calculations. Doh!!!
So the moral of the story is, make sure that you have lots and lots of unit tests around date translations, testing months, day of week, day of month, etc. when you are going between different packages that offer any kind of Date type. It’s not always obvious or even clear if the number values start at 0 or 1.