Using java.util.Calendar to add one day to the date and SimpleDateFormat to display the result, it sometimes seems to lose a day (usually in March), and sometimes skips a day (in November).
The program below, with the release, illustrates the problem. Notice that I just add one day at a time, and then skip a few months and add a few more days. You will see that 2008-03-09 is printed twice, but 2008-11-02 is skipped. The same thing happens in other years, but on different days. I had to experiment to find the days that are causing the problem.
If I do not set the time zone for UTC in SimpleDateFormat, then the problem does not occur. I ran this on a machine in the US Central Time Zone.
This certainly looks like an error in the calendar or SimpleDateFormat, but I could not find it documented anywhere. Anyone explain what is going on here?
Program:
package mab; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; public class CalendarHiccup2 { public static void main(String[] args) { addDays("2008-03-08"); addDays("2009-03-07"); addDays("2010-03-13"); } public static void addDays(String dateString) { System.out.println("Got dateString: " + dateString); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Calendar calendar = Calendar.getInstance(); try { calendar.setTime(sdf.parse(dateString)); Date day1 = calendar.getTime(); System.out.println(" day1 = " + sdf.format(day1)); calendar.add(java.util.Calendar.DAY_OF_MONTH, 1); Date day2 = calendar.getTime(); System.out.println(" day2 = " + sdf.format(day2)); calendar.add(java.util.Calendar.DAY_OF_MONTH, 1); Date day3 = calendar.getTime(); System.out.println(" day3 = " + sdf.format(day3)); calendar.add(java.util.Calendar.DAY_OF_MONTH, 1); Date day4 = calendar.getTime(); System.out.println(" day4 = " + sdf.format(day4));
Output:
Got dateString: 2008-03-08 day1 = 2008-03-08 day2 = 2008-03-09 day3 = 2008-03-09 day4 = 2008-03-10 day5 = 2008-10-31 day6 = 2008-11-01 day7 = 2008-11-03 day8 = 2008-11-04 Got dateString: 2009-03-07 day1 = 2009-03-07 day2 = 2009-03-08 day3 = 2009-03-08 day4 = 2009-03-09 day5 = 2009-10-30 day6 = 2009-10-31 day7 = 2009-11-02 day8 = 2009-11-03 Got dateString: 2010-03-13 day1 = 2010-03-13 day2 = 2010-03-14 day3 = 2010-03-14 day4 = 2010-03-15 day5 = 2010-11-05 day6 = 2010-11-06 day7 = 2010-11-08 day8 = 2010-11-09
source share