Tuesday, June 5, 2012

Obscure SimpleDateFormat Android Issue

This bug should win an award for the most obscure bug I've ever run into this year.

Check out this code below:

Calendar cal1 = new GregorianCalendar(2012, 5, 11);

cal1.setTimeZone(TimeZone.getTimeZone("UTC"));

Calendar cal2 = new GregorianCalendar(2012, 5, 12);

cal2.setTimeZone(TimeZone.getTimeZone("UTC"));

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

df.setTimeZone(TimeZone.getTimeZone("UTC"));

Log.i("test", "cal1.format=" + df.format(cal1.getTime()));

Log.i("test", "cal2.format=" + df.format(cal2.getTime()));

You might expect the two formats to be different (one for May 11, the other for May 12).  You would be wrong on Android 2.2 and lower.  It turns out in this one specific case, the SimpleDateFormat will spit out the same formatted date for the two Calendars.

The conditions seem to be thus:

  1. Two Calendar objects that are one day apart.
  2. One SimpleDateFormat that you want to use.
  3. Both the Calendars and the DateFormat are set to the same TimeZone.
  4. You format both Calendars using the DateFormat, one after another.

In this one situation, SimpleDateFormat gets into a state where it formats both Calendars to the same date (May 11).  Change any of the above assumptions and the problem will not occur; if the Calendars are more than one day apart, or you use multiple SimpleDateFormats, or you don't set the TimeZone, or you don't immediately reuse the same SimpleDateFormat...

This problem does not occur on Android 2.3+.  For Android 2.2 and lower, the solution is simple - create a new SimpleDateFormat when formatting two Calendars one after another.

No comments:

Post a Comment