rakesh
rakesh

Reputation: 304

Execute java program between certain time duration

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

Answers (3)

Basil Bourque
Basil Bourque

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

admlz635
admlz635

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

Phash
Phash

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

Related Questions