我写了一段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点弹出对话框。
答案 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());
当然,请使用您自己在亚洲/重庆地区所处的时区。
链接
java.time
。Timer.scheduleAtFixedRate
documentation