使用GregorianCalendar减24小时出现时间异常的技术问询
问题原因:夏令时(DST)切换导致的时间计算差异
这其实是夏令时(Daylight Saving Time)切换带来的典型问题,不是Java API的bug!
具体背景
2018年3月25日是欧盟地区(以及部分采用夏令时的国家/地区)的夏令时启动日:当天凌晨2点,时钟会被向前拨1小时到3点,也就是说这一天实际的时长只有23小时,而非通常的24小时。
为什么你的代码会得到这个结果?
当你调用gcFinAux.add(Calendar.HOUR_OF_DAY, -24)时,GregorianCalendar会基于实际的时间流转逻辑计算,而不是粗暴地减去86400秒。从2018年3月25日09:41往回倒推24小时,会经过那个“缺失的1小时”(原本的凌晨2点到3点被跳过了),所以最终的时间会比预期少1小时,变成3月24日08:41。
验证与解决方案
我在JDK 1.6.0_45和Java 1.8环境下测试了你的代码,确实得到了和你完全一致的输出:
- 25/03/2018 09:41:00
- 24/03/2018 08:41:00
如果你想要直接减去“一天”而不受夏令时影响,可以改用DAY_OF_MONTH字段进行调整:
// 替换原来的add(HOUR_OF_DAY, -24) gcFinAux.add(Calendar.DAY_OF_MONTH, -1);
修改后输出就会是预期的24/03/2018 09:41:00。
另外你可以测试3月26日的情况:把初始日期改成2018年3月26日09:41,再减24小时,会正常回到3月25日09:41——因为3月25日之后的一天是完整的24小时,没有夏令时切换的影响。
内容的提问来源于stack exchange,提问作者Mastroca
相关产品推荐
相关产品推荐

