Reputation: 304
I have a requirement where I need to run the Java program only between 9AM and 5PM on weekdays. Timezone will be UTC always. The program should start exactly at 9AM and should end before 5PM. If it can't complete before 5PM then it should sleep till next day 08:59:59. If the next day is Weekend then it should start on Monday.
The article difference in seconds between two dates using joda time? explains how to get difference in seconds between two predefined dates but I always want to calculate difference between next working day 9AM and current time.
I'm thinking of using Thread.sleep() by calculating the time difference between two dates. Is there a Joda Time api which I can use to calculate the time difference between two dates?
I already tried getting the current epoch and epoch of next day 9AM if its weekday, calculating the difference between these two epochs and using that value for Thread.sleep but it's little bit messy.
Below is the pseudocode which I used
getNextDayEpoch function contains if/else code to decide if it's a weekday or weekend using Determine if date is weekday/weekend java
Based on whether its weekday or weekend, I get the corresponding epoch value.
currentEpoch = getCurrentEpoch()
nextDayEpoch = getNextDayEpoch()
difference = nextDayEpoch - currentDayEpoch
try {
Thread.sleep(difference);
} catch (InterruptedException e) {
e.printStackTrace();
}
Can you please suggest any better way to do it?
Upvotes: 0
Views: 557
Reputation: 338201
The Joda-Time project is now in maintenance-mode. The creator of Joda-Time, Stephen Colebourne, went on to lead JSR 310 and its implementation in the java.time classes.
Set your limits.
LocalTime ltStart = LocalTime.of( 9 , 0 ) ;
LocalTime ltStop = LocalTime.of( 17 , 0 ) ;
Get current moment as seen in your desired time zone.
ZoneId z = ZoneOffset.UTC ; // Or ZoneId.of( "Africa/Casablanca" ) or such.
ZonedDateTime now = ZonedDateTime.now( z ) ;
Compare the time-of-day.
if( now.toLocalTime().isBefore( ltStart() ) {
// Wait until start
Duration d = Duration.between( now , now.with( ltStart ) ) ;
// Use that duration to schedule task.
}
See if the current moment is within the work time.
if( ( ! now.toLocalTime().isBefore( ltStart ) && ( now.toLocalTime().isBefore( ltStop ) { // do work }
If now is after the stop time, add a day with plusDays
, call with
to set tomorrow to 9 AM, and calculate duration for length of time to wait.
You want the next working day. You could write the code yourself to skip Saturday and Sunday by using the DayOfWeek
enum. But I suggest adding the ThreeTen-Extra library (also led by Stephen Colebourne) to your project. It offers the nextWorkingDay
implementation of TemporalAdjuster
.
// If the current time is on or after the stop time…
if( ! now.toLocalTime().isBefore( ltStop ) ) {
TemporalAdjuster ta = org.threeten.extra.Temporals.nextWorkingDay() ;
ZonedDateTime nextStart = now.with( ltStart ).with( ta ) ;
Duration d = Duration.between( now , nextStart ) ;
// Use duration to schedule next execution.
}
After testing for your three possibilities (before start, within start-stop, and after stop), I recommend adding an "else" as defensive programming to make sure your code is correct.
Thread.sleep(difference);
Sleeping a thread can work, but is a relatively crude way of doing this.
Learn about the Executors framework in Java to make easy work of scheduling tasks. See Oracle Tutorial. And search Stack Overflow as this has been covered many times.
Upvotes: 0
Reputation: 1014
If your are currently using spring in your project, you could try @Scheduled
annotation with a cron param
@Scheduled(cron = "0 0 1 * * ?")
public void doThing() {
//...
}
See https://spring.io/guides/gs/scheduling-tasks/
Upvotes: 0
Reputation: 428
Maybe you want to learn about Scheduling ScheduledExecutorService you can also take a look at the Quartz-Framwork
I would take quartz for this.
Upvotes: 6