Incorrect test - daylight saving time

In the nightly build of Jenkins, one of our tests failed at 2:00:12. After some time debugging and changing the system time of my computer, I was very confused. Then I wrote the following test (simulating a problem) that fails, but I cannot understand why. I tried Google but didn’t find anything. Can someone explain why the last statement fails?

@Test public void testFirstBeforeSecond_atDayLightSavingTime() throws ParseException { Date first = new SimpleDateFormat("dd-MM-yyyy HH:mm").parse("25-10-2015 00:59"); Date second = new SimpleDateFormat("dd-MM-yyyy HH:mm").parse("25-10-2015 01:01"); assertThat(first.before(second), is(true)); // Ok, as expected first = add(first, Calendar.HOUR_OF_DAY, 2); second = add(second, Calendar.HOUR_OF_DAY, 2); assertThat(first.before(second), is(true)); // Ok, as expected first = add(first, Calendar.DAY_OF_YEAR, 2); second = add(second, Calendar.DAY_OF_YEAR, 2); assertThat(first.before(second), is(true)); // Fails? } private Date add(Date date, int field, int amount) { Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("Europe/Brussels")); calendar.setTime(date); calendar.add(field, amount); return calendar.getTime(); } 

(In the time zone in Brussels, summer time ended on 25-10-15 at 3 a.m. Then the clock bounced back an hour.)

+6
source share
1 answer

If you print first and second at each step, this is what you get:

Your first match

 Sun Oct 25 00:59:00 CEST 2015 Sun Oct 25 01:01:00 CEST 2015 

which is exactly what was expected. Twice, two minutes, during Central European Summer Time.

The second match is becoming interesting. You have added two hours to each date:

 Sun Oct 25 02:59:00 CEST 2015 Sun Oct 25 02:01:00 CET 2015 

Now two times switching DST. First time in the summer, 2:59; the second time at standard time, at 2:01.

When you add two days to it, it looks like Java forgets everything about daylight saving time:

 Tue Oct 27 02:59:00 CET 2015 Tue Oct 27 02:01:00 CET 2015 

2:59 and 2:01, just like it was ... it could be two days later on the calendar, but the first time, of course, not 48 hours later than the second step!

If you change the final add-ons to

  first = add(first, Calendar.HOUR_OF_DAY, 48); second = add(second, Calendar.HOUR_OF_DAY, 48); 

then the problem disappears:

 Tue Oct 27 01:59:00 CET 2015 Tue Oct 27 02:01:00 CET 2015 

My guess is that the Java developers had to make some guesses about the expected behavior of what it meant "N days later" when it involved switching DST.

+7
source

All Articles