在Jenkins的每晚构建中,我们的一个测试在凌晨2:00:12失败了.经过一段时间调试和改变我的电脑的系统时间,我很困惑.然后我编写了以下测试(模拟问题),但失败了,但我无法理解为什么.我试过谷歌,但没有发现类似的东西.
谁能解释为什么最后一个断言失败了?
@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();
}
Run Code Online (Sandbox Code Playgroud)
(在布鲁塞尔时区,夏令时结束于25-10-15凌晨3点.时钟然后跳回一小时.)
如果你打印出来first并second在每一步,你得到的是:
你的第一场比赛是
Sun Oct 25 00:59:00 CEST 2015
Sun Oct 25 01:01:00 CEST 2015
Run Code Online (Sandbox Code Playgroud)
这完全符合预期.在中欧夏令时间间隔两次,相隔两分钟.
第二场比赛变得有趣.您为每个日期添加了两个小时:
Sun Oct 25 02:59:00 CEST 2015
Sun Oct 25 02:01:00 CET 2015
Run Code Online (Sandbox Code Playgroud)
现在两次跨越DST切换.第一次是夏季时间,2:59; 第二次是在标准时间,2:01.
当你向它添加两天时,看起来Java会忘记夏令时:
Tue Oct 27 02:59:00 CET 2015
Tue Oct 27 02:01:00 CET 2015
Run Code Online (Sandbox Code Playgroud)
2:59和2:01,完全一样......这可能是两天后的日历,但第一次肯定不比第二步晚48小时!
如果您将最终的添加集更改为
first = add(first, Calendar.HOUR_OF_DAY, 48);
second = add(second, Calendar.HOUR_OF_DAY, 48);
Run Code Online (Sandbox Code Playgroud)
然后问题就消失了:
Tue Oct 27 01:59:00 CET 2015
Tue Oct 27 02:01:00 CET 2015
Run Code Online (Sandbox Code Playgroud)
我的猜测是,Java设计者必须对"N天后"在跨越DST切换时的预期行为做出一些猜测.
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |