如何在特定日期和时间触发 java 中的事件?

How to trigger events in java at specific date and time?

我需要在特定的日期和时间向几个手机号码发送短信。例如我将有一个日期和时间列表以及相应的手机号码列表。如下。

Date                Mobile
10th April 9 AM     1234567890
10th April 11 AM    9987123456,9987123457
11th April 3.30 PM  9987123456

等等。

我知道,java 有 cron 调度程序可以 运行 在特定的时间表。

http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html

我可以运行一个可以继续检查时间的工作,然后如果当前时间与上面列表中的时间匹配,则发送短信。

但在这种情况下,我将不得不一直检查。

有什么办法,我可以在给定的时间直接解雇那些 events/sms。比如为每个日期时间注册工作并在那个时间解雇这些工作,而不是让 运行 连续检查日期时间的工作?

使用Java计时器class在特定时间安排活动。

http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html#schedule(java.util.TimerTask, java.util.Date)

timer.schedule(new DateTimeTask(), date);

这种方法的缺点是它创建了多个 TimerTask 的列表。所以性能取决于您要安排的任务数量。

如何实现某种形式的自定义事件处理程序,并为每次注册回调方法。当每个事件的计时器到达时,您可以从您的工作中启动每个回调方法。

您可以使用 ScheduledExecutorService. See Tutorial.

 private class SmsSenderTask implement Runnable {
     private String text;
     private List<String> phoneNumbers;

     public void run() {
         for (String number : phoneNUmbers) {
             sendSms(number, text);
         }
     }
}

ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
for (Date d : dates) {
    long millis = d.getTime() - System.currentTimeMillis();
    service.schedule(new SmsSenderTask(text, phoneNumbers), millis, TimeUnit.MILLISECONDS);
}

使用java.time

using ScheduledExecutorService 是正确的,应该接受。我在这里解决日期时间角度。

如果可能,请使用标准 ISO 8601 格式将日期时间值序列化为文本。

2017-04-10T09:00:00Z

2017-04-10T11:00:00Z

2017-04-11T15:30:00Z

java.time classes 在解析和生成日期时间值时默认使用 ISO 8601 格式。

Instant instant = Instant.parse( "2017-04-10T09:00:00Z" );

还有,你忽略了时区这个关键问题。上面我的字符串中的 ZZulu 的缩写,意思是 UTC。 Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds(最多九 (9) 位小数)。

如果您必须使用这些不幸格式的字符串,请在 Stack Overflow 中搜索 DateTimeFormatter class 以了解有关解析字符串的更多信息。

如果您的日期时间适用于其他地区的 wall-clock time,则通过 ZoneId 分配时区以获得 ZonedDateTime。在 Stack Overflow 中搜索那些 class 的名字以了解更多信息。

您需要获得一定的毫秒数才能使用 ScheduledExecutorService 安排事件。您必须计算当前时刻与事件的所需 Instant 之间的毫秒数。这样的时间跨度由 Duration class 表示为总秒数加上以纳秒为单位的小数秒。您可以向 Duration 询问它的总时间跨度,以毫秒为单位(截断任何 microseconds/nanoseconds)。

Instant now = Instant.now() ;
Duration d = Duration.of( now , instant ) ;
long millis = d.toMillis();

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

从哪里获得java.time classes?

  • Java SE 8 and SE 9 及更高版本
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and SE 7
  • Android
    • ThreeTenABP 项目专门为 Android 改编 ThreeTen-Backport(如上所述)。
    • 参见

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.