如何每天使用Java在晚上8点(20:00小时)弹出一个对话框?

时间:2018-08-21 19:23:55

标签: java timer calendar popup alarm

我写了一段Java代码,每天晚上8点(20:00小时)弹出一个对话框。但是,该代码仅是第一次工作,而在我更改时间之后,此代码便不再工作。这是我的代码:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;

public class PopUp {

public static void main(String[] args) {
    Timer timer = new Timer();
    TimerTask tt = new TimerTask() {
        @Override
        public void run() {
            Calendar cal = Calendar.getInstance();

            int hour = cal.get(Calendar.HOUR_OF_DAY);
            int min = cal.get(Calendar.MINUTE);
            int sec = cal.get(Calendar.SECOND);

            if (hour == 20 && min == 00 && sec == 0) {
                JOptionPane.showMessageDialog(null, "PopUp Success at "+new Date().toString());
                System.out.println("PopUp Success at "+new Date().toString());
            }
        }
    };
    timer.schedule(tt, 1000, 1000 * 5);
}

}

我的代码有什么问题吗?请Plz帮助我解决此问题,以便每天晚上8点弹出对话框。

1 个答案:

答案 0 :(得分:1)

  

我的代码有什么问题吗?

您的计时器任务将检查时间,精确地是小时,分钟和秒。您正在以5秒(1000 * 5毫秒)的周期性延迟计划此任务。这意味着您不太可能准确打出20:00:00。例如,您可能会在19:59:57进行检查,然后在20:00:02甚至20:00:03进行检查,因为每次检查都会花费一些时间,并且计时永远都不准确。

显然您是第一次幸运,但是还没有成功。

一个可能的解决方法是使用两种重载的scheduleAtFixedRate方法之一,使用期限为1天。然后,您的计时器任务在被调用时可以相信时间已经到了,不需要检查。我将1天指定为TimeUnit.DAYS.toMillis(1),与某些乘法运算相比,它读起来更清晰,并且更容易出错。

您还可以考虑使用操作系统的调度功能,而不是自己编写代码。重新发明轮子通常是一笔不菲的投资。

Calendar已过时

您使用的Calendar类早已过时且设计不佳。我建议您研究一下Java.time(现代的Java日期和时间API)来替代它。

不幸的是,scheduleAtFixedRate​(TimerTask, Date, long)的参数类型至少为过时的java.util.Date。要使用java.time获得Date

    ZoneId zone = ZoneId.of("Asia/Chungking");
    ZonedDateTime at2000 = LocalDate.now(zone)
            .atTime(LocalTime.of(20, 0))
            .atZone(zone);
    if (at2000.isBefore(ZonedDateTime.now(zone))) {
        // Time has passed for today; use tomorrow
        at2000 = at2000.plusDays(1);
    }
    Date dateForScheduler = Date.from(at2000.toInstant());

当然,请使用您自己在亚洲/重庆地区所处的时区。

链接