10

i have looked everywhere to convert seconds into hh:mm:ss but couldn't find the right one

i created a program that allows a user to enter two different times and then calculate the difference

the times entered are split in hh * 3600 - mm * 60 - ss then converted into seconds and subtracted from each other to calculate difference in seconds

for example 12:12:12 and 13:13:13 would give me 3661 seconds but i don't know how to convert the difference back into hh:mm:ss

any help would be appreciated

user3397972
  • 105
  • 1
  • 1
  • 5
  • http://stackoverflow.com/questions/625433/how-to-convert-milliseconds-to-x-mins-x-seconds-in-java –  Mar 20 '14 at 21:37
  • Does this answer your question? [How to convert Milliseconds to "X mins, x seconds" in Java?](https://stackoverflow.com/questions/625433/how-to-convert-milliseconds-to-x-mins-x-seconds-in-java) – karel Jan 09 '23 at 13:38

7 Answers7

15

Using the old java date api (not recommended, see comments):

int sec = .... //
Date d = new Date(sec * 1000L);
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"); // HH for 0-23
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String time = df.format(d);

See also SimpleDateFormat.

Note: as per comments, if the number of seconds exceeds the number of seconds in a day (86400) that won't work as expected. In that case a different approach must be taken.

EDIT: If you're using JDK 8 you can write:

int sec = ...
Duration duration = Duration.ofSeconds(sec);

This duration object better represents what you're talking about. I am trying to find out how to format it as you want to but I have had no luck so far.

EDIT 2: prior to JDK 8 you can use the Joda API:

int sec = ...
Period period = new Period(sec * 1000L);
String time = PeriodFormat.getDefault().print(period); // you can customize the format if this one doesn't cut it

That's probably the most elegant solution. See also this.

EDIT 3: As per comments, I explicitly added the time zone.

Community
  • 1
  • 1
Giovanni Botta
  • 9,626
  • 5
  • 51
  • 94
  • 1
    No, they don't want to convert a date. They want to convert a duration or interval. – Sotirios Delimanolis Mar 20 '14 at 21:38
  • it doesn't make any difference. – Giovanni Botta Mar 20 '14 at 21:39
  • So what date is `3000` milliseconds? – Sotirios Delimanolis Mar 20 '14 at 21:39
  • it's January 1st 1970 at 00:00:03. But you are only printing the time so you will get 00:00:03. – Giovanni Botta Mar 20 '14 at 21:40
  • 1
    What happens if your time zone is off? – Sotirios Delimanolis Mar 20 '14 at 21:47
  • 1
    What happens if it's more than 86,400 seconds? This is the wrong way to do it. – David Conrad Mar 20 '14 at 21:51
  • @DavidConrad I assumed the value will always fit in the hh:mm:ss format. What to do if it exceeds that is unspecified and thus I didn't cover it. Added a note. – Giovanni Botta Mar 20 '14 at 21:57
  • 1
    For `CET` – Central European Time `GMT +1 hour` this will give `01:00:00` for `sec = 0`. Pure match seems easier approach here. – Pshemo Mar 20 '14 at 21:59
  • This is a simple matter of doing some calculations with `int`s; creating `Date` and `DateFormat` objects for it just seems horribly wrong to me. – David Conrad Mar 20 '14 at 22:04
  • `Duration` is a much better suggestion. – Sotirios Delimanolis Mar 20 '14 at 22:06
  • @Pshemo: did you try it? I have used this a million times and never saw that. – Giovanni Botta Mar 20 '14 at 22:07
  • @DavidConrad There is no alternative in native java prior to JDK 8. I believe Joda has a duration/period object. There's nothing "wrong" with using date and a formatter though. – Giovanni Botta Mar 20 '14 at 22:08
  • @GiovanniBotta Yes it is real result for my timezone. – Pshemo Mar 20 '14 at 22:11
  • @GiovanniBotta Really? Because there's another answer to this question that does it with simple calculations, no JDK 8, no Joda Time, no Date, no DateFormat, no Calendar, no nothing. I've written similar code dozens of times in C, C++, and various other languages. The problem is simply to convert a number of seconds into hours, minutes, and seconds (and then format them). – David Conrad Mar 20 '14 at 22:13
  • Still don't see how the above is the wrong way to do it. Home crafted solutions are always error prone and annoying to maintain. In the above, we all know what can go wrong (time zones, more than 24 hrs, etc.). – Giovanni Botta Mar 20 '14 at 22:22
  • Duration.toMinutes() returns the total number of minutes, eg Duration.ofSeconds(3660).toMinutes() returns 61. OP appears to want it to return 1 (or 01). – Phil Feb 08 '18 at 20:02
  • The Joda way of doing it is long winded - new Period(3661 * 1000).toString(new PeriodFormatterBuilder().appendHours().appendLiteral(":").appendMinutes().appendLiteral(":").appendSeconds().toFormatter()) - and it doesn't zero pad the numbers (which may or may not be a problem - this eg returns 1:1:1 not 01:01:01) – Phil Feb 08 '18 at 20:07
12

Just in case you're looking to write your own algorithm for this:

Let's say we have 1000 seconds.

We know that there're 3600 seconds in an hour, so when we format this time as hh:mm:ss, the hh field will be 00. Now let's say we're given a time of 3700 seconds. This time interval is slightly larger than 1 hour, so we know that the hh field will show 01.

So to calculate the number for the hh field, simply divide the provided seconds amount by 3600.

int hours = seconds / 3600

Note that when we have a seconds amount greater than 3600, the result is truncated, so we're left with an integer amount for the hours.

Moving on to the mm field. Again, let's assume we're given a time interval of 3700 seconds. We already know that 3700 seconds is slightly more than 1 hour - we've stored the number of hours in the hour field. To calculate the number of minutes, we'll subtract the hours times 3600 from the provided seconds input:

int minutes = (seconds - hours * 3600) / 60

So if we have a provided time of 3700 seconds, the above code translates to (3700 - 3600) / 60 - we divide by 60 because we want to convert from seconds to minutes.

Finally, the ss field. We use a similar technique as above to calculate the number of seconds.

int seconds = (seconds - hours * 3600) - minutes * 60

public static String formatSeconds(int timeInSeconds)
{
    int hours = timeInSeconds / 3600;
    int secondsLeft = timeInSeconds - hours * 3600;
    int minutes = secondsLeft / 60;
    int seconds = secondsLeft - minutes * 60;

    String formattedTime = "";
    if (hours < 10)
        formattedTime += "0";
    formattedTime += hours + ":";

    if (minutes < 10)
        formattedTime += "0";
    formattedTime += minutes + ":";

    if (seconds < 10)
        formattedTime += "0";
    formattedTime += seconds ;

    return formattedTime;
}
JustSoAmazing
  • 747
  • 4
  • 8
7
    public static void formatSeconds(Integer result){

      System.out.print(String.format("%02d",result/3600)+":");
      System.out.print(String.format("%02d",result/60%60)+":");
      System.out.println(String.format("%02d",result%60));

     }
NetIceGear
  • 252
  • 3
  • 8
4

This is a shorter method:

public static String formatSeconds(int timeInSeconds)
{
    int secondsLeft = timeInSeconds % 3600 % 60;
    int minutes = (int) Math.floor(timeInSeconds % 3600 / 60);
    int hours = (int) Math.floor(timeInSeconds / 3600);

    String HH = ((hours       < 10) ? "0" : "") + hours;
    String MM = ((minutes     < 10) ? "0" : "") + minutes;
    String SS = ((secondsLeft < 10) ? "0" : "") + secondsLeft;

    return HH + ":" + MM + ":" + SS;
}   
  • This looks like a comment not an answer. Please reword your answer. – soundslikeodd Jan 12 '17 at 03:57
  • Is it ok now? I meant to be polite, do not really know how to make it so it won't sound like a comment. – Sebastian Londono Apr 09 '17 at 00:53
  • While this is better than the "longer" version, you can rely on integer division truncating, so you don't need use Math.floor, and instead of using ?: to prepend a leading zero, and string concatenation, you could just return String.format("%02d:%02d:%02d", hours, minutes, secondsLeft);. Although I have seen unverified comments elsewhere about String.format being slow. – Phil Feb 08 '18 at 19:57
2

You can use TimeUnit class to easily convert from seconds to hours, minutes and seconds.

import java.util.Scanner;
import java.util.concurrent.TimeUnit;

class Main {
    public static void main(String[] args) {
        try (Scanner sc = new Scanner(System.in)) {
            long seconds = Long.parseLong(sc.nextLine());

            long HH = TimeUnit.SECONDS.toHours(seconds) % 24;
            long MM = TimeUnit.SECONDS.toMinutes(seconds) % 60;
            long SS = TimeUnit.SECONDS.toSeconds(seconds) % 60;

            System.out.printf("%02d:%02d:%02d%n", HH, MM, SS);
        }
    }
}
AlexGolub
  • 17
  • 1
  • 2
1

I know it's a bit late to answer the question , but never mind. It's basically the same as BarBar1234 answer, but you can combine it all into a single String:

String.format("%02d:%02d:%02d", seconds / 3600, (seconds / 60) % 60, seconds % 60);
Mpi314
  • 11
  • 1
0

Use JODA time libary http://joda-time.sourceforge.net/apidocs/index.html

PeriodFormatter formatter = ... // Define your formatting here
Period firstPeriod = new Period(13, 13, 13, 0);
Period secondPeriod = new Period(12, 12, 12, 0);
Period resultPeriod = firstPeriod.minus(secondPeriod);
String formattedPeriod = formatter.print(resultPeriod);

// Display period e.g. System.out.println(formatterPeriod);
// ....
isak gilbert
  • 2,541
  • 1
  • 14
  • 11