当前 time/date 个事件侦听器

Current time/date event listener

在 java 中有没有办法根据 day/hour 创建一个事件监听器 例如,喜欢 运行 这个代码块每周三 15:30 或 运行 这个代码块在 11 月 15 日 17:30?

ScheduledExecutorService

对于您的两个问题,ScheduledExecutorService 是解决方案。了解 Java 中内置的 Executors framework 使多线程工作更轻松、更可靠。

运行 在特定 date/time

一次

this code block on 15th november at 17.30

执行器服务可以在等待一定时间后运行一个任务。

先确定时刻到运行。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( 2020 , 11 , 15 , 17 , 30 , 0 , 0 , z );

然后定义你的任务运行。

Runnable runnable = new Runnable()
{
    @Override
    public void run ( )
    {
        System.out.println( "Runnable running. " + ZonedDateTime.now( z ) );
    }
};

获取由线程池支持的执行程序服务。

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

计算如何从现在等待到任务需要运行。这里我们使用Durationclass来计算经过的时间。我们传递 Instant 始终采用 UTC 的对象(与 UTC 的零小时-分钟-秒的偏移量)。

long delay = Duration.between( Instant.now() , zdt.toInstant() ).getSeconds();  // Calculate amount of time to wait until we run.

告诉执行程序服务 运行 等待该时间后的任务。确保用于计算 delay 长整数的时间单位与 TimeUnit 参数匹配。

scheduledExecutorService.schedule( runnable , delay , TimeUnit.SECONDS );  // ( Runnable , delay , TimeUnit of delay )

如果您想跟踪该任务的完成情况,请捕获 ScheduledFuture object returned by that schedule 调用。

运行 反复

run this code block on every Wednesday at 15.30

使用与上面类似的代码。在每个任务的运行结束时,计算等待下一个运行的时间,再次调用scheduledExecutorService.schedule。所以任务的一部分工作是安排它的下一个运行。

如果您想按照特定时区中的一天中的时间和一周中的每一天坚持严格的时间表,则必须遵循刚才提到的方法。政客们经常更改其辖区使用的与 UTC 的偏移量,因此天数会有所不同。因此,我们不能将每周任务安排为 7 天 * 24 小时 * 60 分钟 * 60 秒。周长不一,每次都要重新计算。

如果你确实想在完全相同的时间间隔内重复运行,所以你不关心当地时钟的变化,那么使用ScheduledExecutorService.scheduleAtFixedRate​ or ScheduledExecutorService.scheduleWithFixedDelay​。这些已在 Stack Overflow 上多次介绍,因此请搜索以了解更多信息。