I have encountered a very weird behavior while using SimpleDateFormat for parsing a string to a date. Consider the following unit test:
@Test
public void testParse() throws ParseException
{
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String dateStr = "2012-12-21";
Date parsedDate = dateFormat.parse(dateStr);
Calendar date = Calendar.getInstance();
date.setTime(parsedDate);
Assert.assertEquals(2012, date.get(Calendar.YEAR));
Assert.assertEquals(11, date.get(Calendar.MONTH)); // yeah, Calendar sucks
Assert.assertEquals(21, date.get(Calendar.DAY_OF_MONTH));
}
As it can be seen there is an intentional mistake in the above code: the SimpleDateFormat is initialized with "yyyyMMdd" but the string to be parsed is in the format "yyyy-MM-dd". I would expect that such thing results in a ParseException, or at least be parsed on a best-effort basis correctly. Instead, for some weird reason the date is parsed as 2011-11-02. Eh?!
This is unacceptable as one single mistake while handling the inputs would result in something totally unexpected / devastating. Switched to JodaTime in the meantime, but it would be nice to understand what went wrong there.
Well, the input would be split into 3 components: year, month, day and you’d get
month = -12andday = -21(for correction see below). Try to parse2012/12/21and you’ll get the exception 🙂Edit: excerpt from the JavaDoc:
Edit2: Correction
Looking at the source of
SimpleDateFormatit seems that2012-12-21is actually split into this:The source comments state that a
-following a number might either denote a negative number (depending on the locale) or be a delimiter. In your case it seems to be taken as a delimiter, thusday = "2-"results inday = 2, hence the second of November.