6

I want to convert seconds into HH:mm:ss time format, so:

seconds = 3754 
result  = 10:25:40 

I know about the conventional approach of dividing it by 3600 to get hours an so on, but was wondering if I can achieve this through Java API?

Jacob Jan Tuinstra
  • 1,197
  • 3
  • 19
  • 50
user523956
  • 501
  • 2
  • 9
  • 23

3 Answers3

11

Using java.util.Calendar:

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.MILLISECOND, 0);      
    calendar.set(Calendar.SECOND, 37540);
    System.out.println(new SimpleDateFormat("HH:mm:ss").format(calendar.getTime()));
david a.
  • 5,283
  • 22
  • 24
  • At two times per year in countries/time-zones with dst change this code is broken. – Meno Hochschild Feb 24 '14 at 13:19
  • Have checked again: Well, clear() resets the date to 1970-01-01 where there is probably no dst change, so your code is correct in old jdk stuff. – Meno Hochschild Feb 24 '14 at 13:25
  • Well, it was a good point anyway. Time value always depends on date and time zone. I have modified the answer so the current date is kept (and thus taken into account on DST change days). However, the question does not say whether DST shall be taken into account or not, so it is up to the asker to choose whether to clear() , or set hour, minute and ms fields to 0. – david a. Feb 24 '14 at 13:30
  • @david Thank you for your answer. Could you please tell me how can I convert time in HH:mm or HH:mm:ss to seconds using calender class ? Thanks. – user523956 Feb 24 '14 at 20:13
  • @david: it gives 15:34 for both 56040 and 56099 seconds. I expect it to give me 15:35 for 56099. Any idea how can I make it round off when there are more than 30 seconds ? I tried:- if (calendar.get(Calendar.SECOND) >= 30) calendar.add(Calendar.MINUTE, 1); calendar.set(Calendar.SECOND, timeInSeconds); but did not help.. – user523956 Feb 25 '14 at 17:34
  • 56099 matches 15:34:59, so that is actually correct. If you want minutes to increase every :30, rather than :00, the first thing that comes to mind (well, without much thinking so it might be wrong) is `calendar.set(Calendar.SECOND, 56099 + 30)`. – david a. Feb 26 '14 at 10:41
1

Updated and corrected my answer:

In my own library Time4J (v1.2) a pattern-based solution ready for Java 6 and later looks like:

Duration<?> dur = 
  Duration.of(37540, ClockUnit.SECONDS).with(Duration.STD_CLOCK_PERIOD);
String s = Duration.Formatter.ofPattern("hh:mm:ss").format(dur);
System.out.println(s); // 10:25:40

In Joda-Time following code is possible using a builder approach:

PeriodFormatter f =
  new PeriodFormatterBuilder().appendHours().appendLiteral(":").appendMinutes()
  .appendLiteral(":").appendSeconds().toFormatter();
System.out.println("Joda-Time: " + f.print(new Period(37540 * 1000))); // 10:25:40

My previous posted solution was a field-based-workaround (using the field SECOND_OF_DAY) which has a serious disadvantage, namely to be limited to seconds less than 86400 (day-length). The accepted answer using old Calendar-code suffers from this bug, too, so it is not a real solution. In Java-8 (containing a new time library - JSR-310) there is also no solution available because it still misses the possibility to format durations. Sample outputs of the different proposals:

input = 337540 seconds (almost 4 days)
code of accepted solution => 21:45:40 (WRONG!!!)
Time4J-v1.2 => 93:45:40
Joda-Time => 93:45:40

Conclusion, use an external library for solving your problem.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
1

LocalTime

The java.time classes built into Java can do this. The LocalTime class represents a time-of-day without a date and without a time zone. This class includes the concept of second-of-day, how many seconds from the start of the day.

LocalTime lt = LocalTime.ofSecondOfDay( 3_754L );

But the result is not close to what you showed in your Question.

lt.toString(): 01:02:34

Duration

Do not use a time-of-day to represent elapsed time. Confusing and ambiguous. Don’t use a time-of-day class and don’t use a time-of-day style of string formatting.

For elapsed time in the range of day-hours-minutes-seconds, use the Duration class.

Duration d = Duration.ofSeconds( 3_754L );

d.toString(): PT1H2M34S

That output is a String generated in the standard ISO 8601 format of PnYnMnDTnHnMnS where the P marks the beginning and the T separates the years-month-days portion from the hours-minutes-seconds portion. So the result seen above means “one hour, two minutes, and thirty-four seconds”.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154