The Answer by Nairn is correct. Here is detail about coding to set the schedule once you have restarted the Java app.
ScheduledExecutorService
If using the ScheduledExecutorService
interface to schedule you recurring task, one of the arguments is initialDelay
. You specify the amount of time to wait until the first occurrence of your task. After that one-time delay, then your task is scheduled to reoccur after every amount of time specified by another argument, period
.
So after every restart, you compare the current moment to the moment desired for that first run. The span of time in between is the amount you specify as the initialDelay
argument.
First get the current moment.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Set the time-of-day you desire (target) on the same day.
LocalTime target = LocalTime.of( 20 , 0 );
ZonedDateTime then = ZonedDateTime.of( now.toLocalDate() , target , z );
Check to see if that time-of-day today has already past. If past, add a day to get to the day after.
if ( ! then.isAfter( now ) ) { // If already past our target of 8 PM today, move to tomorrow.
then = then.plusDays( 1 );
}
Calculate the span of time (Duration
) between now and that future moment when we want to run the first occurance of our task.
Duration initialDelay = Duration.between( now ; then );
Specify how often we want to run this task (period
) as a Duration
object.
Duration period = Duration.ofHours( 24 );
Translate our pair of Duration
objects to some number of minutes or seconds or milliseconds or whatever granularity you desire. Keep in mind that your task does not at the exact split-second you desire. Your task may be delayed for reasons such as scheduling of the thread’s execution or because the next run of your task is waiting for the previous run to complete. So I suspect TimeUnit.SECONDS
or even minutes is a fine-enough granularity for a daily task.
myScheduledExecutorService.scheduleAtFixedRate(
myRunnable ,
initialDelay.getSeconds() ,
period.getSeconds() ,
TimeUnit.SECONDS
) ;
To recap:
- The
initialDelay
is the span of time used once after your app restarts, to schedule the first run of your task.
- The
period
is the span of time used in repeatedly running your task.