我将如何在特定时间执行事件
How Would I Execute an Event at a Specific Time
目前我正在尝试创建一个计时器,每周在特定时间(星期四下午 1:00)通知我。我现在面临的问题是如何在不执行任何操作的情况下触发计时器启动。我需要定时器每次在机器人启动时自行启动。感谢任何帮助。
这是我的代码:
public class Reminder extends ListenerAdapter {
@Override
public void onGuildMessageReceived(GuildMessageReceivedEvent e) {
if (e.getGuild().getId().equalsIgnoreCase("77804326694381163")) {
TextChannel defaultChannel = e.getGuild().getDefaultChannel();
if (defaultChannel != null) {
Calendar time = Calendar.getInstance();
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
time.setTimeZone(TimeZone.getTimeZone(zoneId));
Date timeGet = time.getTime();
DateFormat df = new SimpleDateFormat("EE HH:mm:ss");
String string = df.format(timeGet);
if (string.equalsIgnoreCase("Thu 13:00:00")) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
defaultChannel.getChannel().sendTyping().queue();
defaultChannel.getChannel().sendMessage("Works").queue();
}
}, time.getTime(), TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS));
}
} else if (defaultChannel == null) {
e.getChannel().sendTyping().queue();
e.getChannel().sendMessage("Failed to get default channel.").queue();
}
}
}
}
我建议你使用 ScheduledExecutorService
。
ScheduledExecutorService scheduledActivity = Executors.newScheduledThreadPool(1);
scheduledActivity.scheduleAtFixedRate(() -> {
//whatever you want to do at 11 PM on Thursday
},
initialDelay, //you have to calculate an initial delay
TimeUnit.DAYS.toSeconds(7), //makes it run every 7 days
TimeUnit.SECONDS);
initalDelay
始终是当前时间与您希望服务到 运行 的时间之间的时差(在您的情况下是星期四晚上 11 点)。
关于如何实现这一点有多种解决方案,但我个人更喜欢以下方法:
//you might want to change the timezone to your liking
LocalDateTime now = LocalDateTime.now(ZoneId.of("Europe/Berlin"));
LocalDateTime then = LocalDateTime.now(ZoneId.of("Europe/Berlin"));
//then equals the next or current Thursday on 13:00 (or 1 PM)
then = then.with(TemporalAdjusters.nextOrSame(DayOfWeek.THURSDAY)).withHour(13).withMinute(0).withSecond(0);
Duration duration = Duration.between(now, then);
long initialDelay = duration.getSeconds();
//initialDelay can become negative if the current day is Thursday but it's already too late
if (initialDelay < 0) {
//add one week to shift the delay to the next correct time
initialDelay = Duration.between(now, localDate.with(TemporalAdjusters.next(DayOfWeek.THURSDAY)).withHour(13).withMinute(0).).getSeconds();
}
(这个绝对可以优化!)
目前我正在尝试创建一个计时器,每周在特定时间(星期四下午 1:00)通知我。我现在面临的问题是如何在不执行任何操作的情况下触发计时器启动。我需要定时器每次在机器人启动时自行启动。感谢任何帮助。
这是我的代码:
public class Reminder extends ListenerAdapter {
@Override
public void onGuildMessageReceived(GuildMessageReceivedEvent e) {
if (e.getGuild().getId().equalsIgnoreCase("77804326694381163")) {
TextChannel defaultChannel = e.getGuild().getDefaultChannel();
if (defaultChannel != null) {
Calendar time = Calendar.getInstance();
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
time.setTimeZone(TimeZone.getTimeZone(zoneId));
Date timeGet = time.getTime();
DateFormat df = new SimpleDateFormat("EE HH:mm:ss");
String string = df.format(timeGet);
if (string.equalsIgnoreCase("Thu 13:00:00")) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
defaultChannel.getChannel().sendTyping().queue();
defaultChannel.getChannel().sendMessage("Works").queue();
}
}, time.getTime(), TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS));
}
} else if (defaultChannel == null) {
e.getChannel().sendTyping().queue();
e.getChannel().sendMessage("Failed to get default channel.").queue();
}
}
}
}
我建议你使用 ScheduledExecutorService
。
ScheduledExecutorService scheduledActivity = Executors.newScheduledThreadPool(1);
scheduledActivity.scheduleAtFixedRate(() -> {
//whatever you want to do at 11 PM on Thursday
},
initialDelay, //you have to calculate an initial delay
TimeUnit.DAYS.toSeconds(7), //makes it run every 7 days
TimeUnit.SECONDS);
initalDelay
始终是当前时间与您希望服务到 运行 的时间之间的时差(在您的情况下是星期四晚上 11 点)。
关于如何实现这一点有多种解决方案,但我个人更喜欢以下方法:
//you might want to change the timezone to your liking
LocalDateTime now = LocalDateTime.now(ZoneId.of("Europe/Berlin"));
LocalDateTime then = LocalDateTime.now(ZoneId.of("Europe/Berlin"));
//then equals the next or current Thursday on 13:00 (or 1 PM)
then = then.with(TemporalAdjusters.nextOrSame(DayOfWeek.THURSDAY)).withHour(13).withMinute(0).withSecond(0);
Duration duration = Duration.between(now, then);
long initialDelay = duration.getSeconds();
//initialDelay can become negative if the current day is Thursday but it's already too late
if (initialDelay < 0) {
//add one week to shift the delay to the next correct time
initialDelay = Duration.between(now, localDate.with(TemporalAdjusters.next(DayOfWeek.THURSDAY)).withHour(13).withMinute(0).).getSeconds();
}
(这个绝对可以优化!)