DevRight
DevRight

Reputation: 395

Issue Converting seconds to HH:MM:SS java

I have a long variable which represents the downtime of an application in seconds. I want to display the downtime as HH:mm:ss

Long downTime = 755; 
Date newD = new Date(downTime * 1000);

When passing the long variable to the Date I multiplied it 1000 to get the millisecond value. The newD variable evaluates to Thu Jan 01 01:12:35 GMT 1970

The value of newD is off by 1 hour, 755 seconds is = 00:12:35

It was my understanding that seconds * 1000 = milliseconds will evaluate to the correct answer. As I seen here

If I use Duration we get the right answer.

Duration d = Duration.ofSeconds(downTime);
PT12M35S

But the formatting is not as I want it.

Upvotes: 0

Views: 2068

Answers (3)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79085

You are almost there

java.time.Duration is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenience methods were introduced.

If you have gone through the above links, you might have already noticed that PT12M35S specifies a duration of 12 minutes 35 seconds. Since you have already got Duration object, out of this object, you can create a string formatted as per your requirement by getting days, hours, minutes, seconds from it.

Demo:

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        Long downTime = 755L;
        Duration duration = Duration.ofSeconds(downTime);// PT12M35S

        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%02d:%02d:%02d", duration.toHours() % 24,
                duration.toMinutes() % 60, duration.toSeconds() % 60);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%02d:%02d:%02d", duration.toHoursPart(), duration.toMinutesPart(),
                duration.toSecondsPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

Output:

PT12M35S
00:12:35
00:12:35

Learn about the modern date-time API from Trail: Date Time.

Duration and date are different concepts

Your requirement is to calculate the duration instead of a date-time. SimpleDateFormat or java.time.format.DateTimeFormatter (part of the modern date-time API) should be used to represent a date/time/date-time i.e. something which represents a point in time instead of a period/duration of time. A thumb rule to remember this is:

  1. Use SimpleDateFormat or java.time.format.DateTimeFormatter for something which you refer with since in English grammar Tense.
  2. Use Period and Duration for something which you refer with for in English grammar Tense.

Check The Difference between Since and For – English grammar

Upvotes: 0

Basil Bourque
Basil Bourque

Reputation: 338730

LocalTime.MIN

LocalTime.MIN.plusSeconds( 755L ) 

Or,

LocalTime.MIN.plus( 
    Duration.ofSeconds( 755L ) 
)

CAVEAT: This is a hack, and I do not recommend it. Representing a span-of-time as a time-of-day is ambiguous and confusing.

By default, the LocalTime::toString method omits the trailing units if zero. To force all three parts (hours, minutes, seconds), use a DateTimeFormatter.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "HH:mm:ss" ) ;
String output = lt.format( f ) ;

See this code run live at IdeOne.com.

00:12:35

ISO 8601

I suggest, if possible, to train your users on the standard ISO 8601 format. This format is practical, clear, and unambiguous. The standard formats are used by default in the java.time classes for parsing/generating strings.

PT12M35S

Or generate a string spelling out the amount of time in prose.

Upvotes: 3

dar24
dar24

Reputation: 31

Check if you can use this:

long millis = 755000;
String hms = String.format("%02d:%02d:%02d", 
    TimeUnit.MILLISECONDS.toHours(millis),
    TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1),
    TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1));
System.out.println(hms);

Upvotes: 2

Related Questions