环境:Amazon Linux AMI 上的 Java 7(已修补)。请注意,在此环境中使用 NTP。
我们的一部分代码定期执行计划任务。通常,执行的确切时间并不是特别重要。但是,我们有类似的逻辑用于计算报告的间隔。报告期预计将落在确切的小时范围内。
示例代码:
protected Calendar increment(ScheduledPeriodEnum scheduledPeriod, Calendar date) {
Calendar next = CalendarUtils.getCalendar();
next.setTimeInMillis(date.getTimeInMillis());
switch (scheduledPeriod) {
case ONE_DAY:
next.add(Calendar.DAY_OF_MONTH, 1);
break;
case ONE_HOUR:
next.add(Calendar.HOUR_OF_DAY, 1);
break;
case FIFTEEN_MINUTE:
next.add(Calendar.MINUTE, 15);
break;
case ONE_MONTH:
next.add(Calendar.MONTH, 1);
break;
default:
throw new RuntimeException("Unhandled case: " + scheduledPeriod);
}
return next;
}
我们将时间保存为 unix 时间戳(长)值。所有Calendar
实例都在 UTC 时区。
我们的理解是 Java 7 的日历实现不考虑闰秒。我们也相信 NTP 会更新操作系统时钟。
我们知道亚马逊 2012 年的闰秒崩溃。我们正在与他们直接沟通,以了解他们的运营准备情况。
具体问题:
如果我们
increment
的日历在闰秒之前的一个小时边界上,它会在闰秒之后的一个小时边界上吗?还是整点前一秒?我们应该如何测试/验证这段代码将如何跨越闰秒边界?被黑的 NIST 跳跃文件是一个好方法吗?
是否有更合适的模式/实现可以回避闰秒问题?