kei
kei

Reputation: 13

Java - Change current time and count up

I'm new to stackoverflow and it's helped me a lot in my first semester of Java. I recently encountered an issue that I could not find help for anywhere. After looking through just about every stackoverflow thread and other sites, I decided to ask here. I'd really appreciate any help with this.

My homework assignment says we need to create a digital clock which takes the user input of hours, minutes, and seconds from the function call in Main. It should then output this time and continue increasing the time. The instructions gave a hint to take the time difference with the current time, but I could not get the correct time this way. This is my current code for the setTime and displayTime functions:

    public void setTime(int InsertHours, int InsertMinutes, int InsertSeconds) {
        minutes = InsertMinutes;
        hours = InsertHours;
        seconds = InsertSeconds;
        currentTime.set(Calendar.HOUR, hours);
        currentTime.set(Calendar.MINUTE, minutes);
        currentTime.set(Calendar.SECOND, seconds);
    }

    public void displayTime()
    {
        SimpleDateFormat newTimeFormat = new SimpleDateFormat("hh:mm:ss a");
        timeDiff = Math.abs(currentTime.getTimeInMillis() - System.currentTimeMillis());

        System.out.print("The current time after setTime: " + newTimeFormat.format(timeDiff));
    }
}

If I call the function like this (without the hours: text)

d.setTime(hours: 10, minutes: 25, seconds: 56);

The output is:

The current time after setTime: 07:42:22 PM

and it will count backwards. So this will go from 7:42:22 to 7:42:19 and so on. I would like this to output 10:25:56 and continue counting up, but I've spent several hours on this and cannot figure it out. I noticed others do this with a separate timeTick() function, but I would like to avoid any extra functions rather than setTime and displayTime. I'd really appreciate any help with this. Thanks!

Upvotes: 1

Views: 712

Answers (3)

Hector Zeledon
Hector Zeledon

Reputation: 21

I think I would use the same aproach as Scary Wombat, try next code:

    Scanner scanner = new Scanner(System.in);
    //Reading values for hours, minutes and seconds
    System.out.print("Hours: ");
    int h = scanner.nextInt();
    System.out.print("Minutes: ");
    int m = scanner.nextInt();
    System.out.print("Seconds: ");
    int s = scanner.nextInt();
    System.out.println();

    do{ //Creating an infinite loop while program is running
        if (s+1 == 60){ //Controlig the seconds updates
            s=1;
            if (m+1 == 60){//Controling the minites updates
                m=0;
                h+=1; // Here you could control hours updates
            }else{
                m+=1;
            }
        }else{
            s+=1;
        }
        System.out.println(String.valueOf(h)+":" +String.valueOf(m) + ":"+String.valueOf(s));
        Thread.sleep(1000);//Deelaying execution 1 second
    }while(true);

In this case you just have to complete the code to control hours updates

Upvotes: 0

Anonymous
Anonymous

Reputation: 86296

java.time

First I would skip Calendar and SimpleDateFormat. Those classes were poorly designed and are now long outdated. Instead I would instantiate a LocalTime object from the hour, minute and second that the user has entered. A LocalTime is a time of day without date and without time zone.

I would probably use a java.util.Timer for displaying a new value every time one second has passed. Its scheduleAtFixedRate(TimerTask, long, long) method executes your TimerTask once every second if you pass a period of 1000 (milliseconds) to it. If you want a more bare-bones approach, the answer by Scary Wombat provides one that requires no Timer nor TimerTask.

In your TimerTask add 1 second to your LocalTime using its plusSeconds method and remember that this method returns a new LocalTime object that you need to use. Then display it using a DateTimeFormatter. DateTimeFormatter.ofLocalizedTime() will give you an appropriate formatter for your locale.

What went wrong in your code?

You haven’t given us a complete example, so it’s hard to be completely sure, but it seems that this is what happened:

  • You created a Calendar object representing the current date and time.
  • You set its time within AM or PM to the time the user has entered. If for example at 02:43:34 PM the user enters 10:25:56, the Calendar will be set to 10:25:56 PM on the same day.
  • In displayTime() you calculate the difference between the current time and the Calendar object in milliseconds. If the Calendar time is in the future (as in the example), this difference will be ever smaller until the Calendar time is reached, which explains why your clock is counting down instead of up.
  • You are displaying the time difference using a SimpleDateFormat with your default time zone. This is wrong. The formatter takes your number as a count of milliseconds since the epoch of January 1, 1970 at 00:00 UTC and converts this time to your time zone. For a simple example, if the difference happened to be 1000 milliseconds (1 second), it would display 00:00:01 UTC. If your time zone was America/New_York, your time would be 19:00:01 on the evening before, so 07:00:01 PM would be displayed.

Links

PS: When you search the web, it’s so easy to get the impression that Calendar and SimpleDateFormat are classes to use since so many old web pages still lie around from the time when this was the case. And there are even more of them exactly because those classes were complicated to use and therefore needed explanation. Those pages no longer tell the truth about the good classes to use for date and time operations. Use java.time instead. Always.

Upvotes: 2

Scary Wombat
Scary Wombat

Reputation: 44844

With out all the fancy formatting of your date (and making sure that it is a proper date) the basic flow of the code would be like

int h = 1, min = 5, sec = 10;
long start = System.currentTimeMillis();
while (true) {  // or whatever
    long now = System.currentTimeMillis();
    long offset = now - start;
    System.out.println(sec + (offset / 1000));
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
         e.printStacktrace();
    }

}

Upvotes: 1

Related Questions