Phantom Fangs
Phantom Fangs

Reputation: 57

Calendar seconds are not increasing in while loop

I am trying to make the while loop stop after 5 seconds and a half (5.5) so I am using the Calendar library to get the current second of the minute and then increment 5.5 onto it. After that process it loops round waiting for the current time to be equal to the saved variable

I realised that the seconds are NOT increasing... why is that?

Code:

package me.fangs.td;

import java.util.Calendar;

public class Main {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        double timeout = calendar.get(Calendar.SECOND) + 5.5;
        while((double) calendar.get(Calendar.SECOND) < timeout) {
            System.out.println((double) calendar.get(Calendar.SECOND));
            Thread.sleep(1000);
        }
    }
}

Upvotes: 1

Views: 335

Answers (3)

Basil Bourque
Basil Bourque

Reputation: 339332

java.time

The Answer by VoroX is correct. But using java.time makes it more elegant and self-documenting.

We call Instant.now each time through the loop to capture the new current time. The date-time objects are not auto-updating. They are a snapshot of that moment, frozen. Ask in each case when you want the current time.

Duration wait = Duration.ofSeconds( 5 ).plusMillis( 500 ) ;  // 5.5 seconds.
Instant now = Instant.now() ;
Instant stop = now.plus( d ) ;

while( Instant.now().isBefore( stop ) ) 
{
   // Do some task. 
} 

In real work I would also add a check that stop.isAfter( start ) in case the Duration ever got edited to be negative.

Upvotes: 1

VoroX
VoroX

Reputation: 247

I wouldn't use the Calender library at all, instead I'd use System.currentTimeMillis()

Here's a while loop which terminates after 5.5 seconds:

long end = System.currentTimeMillis() + 5500;
while (System.currentTimeMillis() < end) {
  //Do something
}
//Exit after 5.5 seconds

This version has the advantage, that you can change the end time while the loop is running, changing the time the loop will run.

Upvotes: 2

Elliott Frisch
Elliott Frisch

Reputation: 201467

Instead of implementing my own, I would prefer / use Timer which is a facility for threads to schedule tasks for future execution in a background thread. Like,

Timer t = new Timer();
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        System.out.println("Five seconds");
    }
};
t.schedule(task, TimeUnit.SECONDS.toMillis(5) + 500); // 5.5 seconds.

Upvotes: 2

Related Questions