0

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.

Jonas
  • 2,139
  • 17
  • 38
DevRight
  • 345
  • 1
  • 6
  • 25
  • 2
    Take a look here for how to format duration: https://stackoverflow.com/questions/266825/how-to-format-a-duration-in-java-e-g-format-hmmss. – aUserHimself Sep 08 '17 at 09:29
  • 3
    Your current code would work if you were in UTC, your local timezone must be one hour ahead of UTC. – Elliott Frisch Sep 08 '17 at 09:30
  • 4
    Also, if you have access to the Duration class, it means you're using Java 8. So don't use the old Date class anymore. Use classes from the java.time package. – JB Nizet Sep 08 '17 at 09:34
  • try using `Date newD = new Date(System.currentTimeMillis() + downTime * 1000);` that should provide you the system's current time. – Procrastinator Sep 08 '17 at 09:45
  • 2
    Just saying, but if you use `java.time.Duration`, at least use complete the `java.time` package, not `java.util.Date`. – AxelH Sep 08 '17 at 09:53
  • 1
    @procrastinator The Question is not asking for the current time at all. The Question is about hacking a time-of-day format for a span-of-time. Also, avoid the legacy classes. Much easier to just use the modern java.time classes. `LocalTime.MIN.plusSeconds( 755L ).toString()` – Basil Bourque Sep 08 '17 at 09:59

3 Answers3

3

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 2
    I agree that this hack could be confusing. `Duration` exist (and is know by OP) to represent a duration... using it it the solution. – AxelH Sep 08 '17 at 10:08
2

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);
AxelH
  • 14,325
  • 2
  • 25
  • 55
dar24
  • 39
  • 5
0

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

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110