4

startDateendDate、および発生(毎時、毎日、毎週、毎月、月曜日など) に基づいてリマインダーを送信する Java のスケジューリング システムに取り組んでいます。もともと、リマインダーをスケジュールするためにTimerおよびTimerTaskクラスを使用していました。

Timer timer = new Timer();
timer.scheduleAtFixedRate(reminder, firstDate, period);

最近、 ScheduledExecutorServiceに切り替えたので、イベントのキャンセルをより細かく制御できるようになりました。ScheduledExecutorServiceは、過去の startDate でリマインダー再スケジュールする 1 つのケースを除いて、定期的なリマインダーに対してうまく機能しています。scheduleAtFixedRate関数では、実際のDateオブジェクトではなく、 initialDelayにlong値のみを指定できます。

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(reminder, initialDelay, period, unit);

負のinitialDelayを渡すと、イベントがすぐに発生し、 startDate + periodではなくnow + periodで再発するため、これは問題を引き起こします。

過去のstartDateでリマインダーを (再) スケジュールする方法はありますか?

4

2 に答える 2

2

日付が過去のものであるかどうかを簡単に確認してから、現在の過去の開始の増分である新しい一時的な開始日時を作成します。

于 2010-07-07T16:45:44.237 に答える
0

起動時に一度実行してから、毎日必要な時間に実行することで解決しました。

// check once initial on startup
doSomething();

// and then once every day at midnight utc
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
LocalDateTime firstRun = LocalDate.now(ZoneOffset.UTC).atStartOfDay().plusDays(1);
Duration durationUntilStart = Duration.between(LocalDateTime.now(ZoneOffset.UTC), firstRun);
scheduler.scheduleAtFixedRate(
        () -> doSomething(),
        durationUntilStart.getSeconds() + 1,
        Duration.ofDays(1).getSeconds(),
        TimeUnit.SECONDS
);
于 2018-05-05T16:14:07.867 に答える