首先,“发生在午夜”的定义是当任务运行时,new DateTime()
或类似的将在转换为人类可读格式时显示 00:00:00 或更晚的时间部分。重要的一点是它不能显示前一天的 23:59:59。
实现此目的的一种常见方法是计算从现在到所需时间点的毫秒数,然后使用 aScheduledExecutorService
在正确的时间执行任务。但是,当插入闰秒时,这将导致任务提前一秒运行(或提前几毫秒,具体取决于闰秒的“涂抹”方式以及您安排任务的时间):
Runnable task = ...
long numberOfMillisUntilMidnight = ...
ScheduledExecutorService executor = ...
// task runs too early when leap seconds are inserted
executor.schedule(task, numberOfMillisUntilMidnight, TimeUnit.MILLISECONDS);
原因是executor.schedule()
基于System.nanoTime()
它显然忽略了闰秒。我想我需要的是一些基于“此时运行”而不是“在这段时间后运行”的调度程序。
对于那些感兴趣的人来说,任务必须在午夜运行的原因与我系统中的所有事件必须根据它们发生的日期分类这一事实有关,并且在可能的情况下,这需要与另一个系统。当然,如果另一个系统在每个事件上标上今天的日期会更好,但我们不在那里。