Wednesday, November 6, 2013

SimpleDateFormat sillyness

Ran into an amazingly dumb bug yesterday. I would say that this is clearly a bug in the behavior of SimpleDateFormat in Java. Why is it that when I give it a date that looks valid, and a format string that's not right, and in fact contains invalid numbers, it will go ahead and parse my date string producing a ridiculous result. But not so ridiculous it's obvious, or in fact, just throws an Exception, which for my money would be the desired outcome.

So this is the scenario. Parsing a date like this:

val dateStr = "2013-02-04 05:35:24.693 GMT"

with the date parsing string:

val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss.SSS z")

If you're paying very close attention, you will see the problem here; the month component is repeated. This yields the following date in the resulting Date object: "Tue Nov 03 21:00:24 PST 2015"

This result is clearly very different than what was sent in. I see two problems here. The date string contained two references to the same field. I can see where sometimes this might be useful, but honestly, I feel like you should have to set a flag or something for this to be silently ignored. In most cases having a reference to the same part of a date within a format string seems like a warning flag at least. The second problem is that the erroneous value for month that was give is beyond the scope of a calendar year. You can't have 35 months in a year. In my opinion this should have thrown an exception. I understand that potentially in some calendar system somewhere on this earth there maybe more than 35 'months' in a year or something, but this is very unexpected behavior, way outside of what I would considered normal.

In short, if you have a date string that is being parsed and coming out the other end with a very strange unexpected and wrong result, there's a good chance the format string is off, and probably only very slightly and in a way that's hard to spot without a very very careful eye.