147

I've been trying to convert a value of seconds (in a BigDecimal variable) to a string in an editText like "1 hour 22 minutes 33 seconds" or something of the kind.

I've tried this:

String sequenceCaptureTime = "";
BigDecimal roundThreeCalc = new BigDecimal("0");
BigDecimal hours = new BigDecimal("0");
BigDecimal myremainder = new BigDecimal("0");
BigDecimal minutes = new BigDecimal("0");
BigDecimal seconds = new BigDecimal("0");
BigDecimal var3600 = new BigDecimal("3600");
BigDecimal var60 = new BigDecimal("60");

(I have a roundThreeCalc which is the value in seconds so I try to convert it here.)

hours = (roundThreeCalc.divide(var3600));
myremainder = (roundThreeCalc.remainder(var3600));
minutes = (myremainder.divide(var60));
seconds = (myremainder.remainder(var60));
sequenceCaptureTime =  hours.toString() + minutes.toString() + seconds.toString();

Then I set the editText to sequnceCaptureTime String. But that didn't work. It force closed the app every time. I am totally out of my depth here, any help is greatly appreciated.

starball
  • 20,030
  • 7
  • 43
  • 238
rabbitt
  • 2,558
  • 8
  • 28
  • 41
  • 1
    possible duplicate of [How to convert Milliseconds to "X mins, x seconds" in Java?](http://stackoverflow.com/questions/625433/how-to-convert-milliseconds-to-x-mins-x-seconds-in-java) – Richard Schneider May 25 '11 at 02:39
  • Any reason why you are using BigDecimal instead of BigInteger? – Ted Hopp May 25 '11 at 02:42
  • I will have to implement fractions of a second later on in dev, right now I am just trying to get the calculation to work in the first place. – rabbitt May 25 '11 at 02:49
  • 1
    I second Richard's comment - you can use the TimeUnit enum to do a lot of the work for you. http://developer.android.com/reference/java/util/concurrent/TimeUnit.html – Ben J May 25 '11 at 03:05
  • How would I go about using timeunit to convert from a BigDecimal with seconds in it to HHMMSS? – rabbitt May 25 '11 at 06:44

22 Answers22

300

Is it necessary to use a BigDecimal? If you don't have to, I'd use an int or long for seconds, and it would simplify things a little bit:

hours = totalSecs / 3600;
minutes = (totalSecs % 3600) / 60;
seconds = totalSecs % 60;

timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds);

You might want to pad each to make sure they're two digit values(or whatever) in the string, though.

Geobits
  • 22,218
  • 6
  • 59
  • 103
  • I will have to implement fractions of a second later on in dev, right now I am just trying to get the calculation to work in the first place. – rabbitt May 25 '11 at 02:49
  • 13
    `String.format("%02d:%02d:%02d", hours, minutes, seconds);` – Jeffrey Blattman Apr 30 '14 at 20:56
  • This is simply impressive. I wonder how modulus could work in this way. – PSo Sep 13 '16 at 09:11
  • Use Locale otherwise it will gives you warning. `String.format(Locale.ENGLISH, "%02d:%02d:%02d", hours, minutes, seconds)` – Pratik Butani Jan 10 '17 at 05:06
  • 3
    Whenever you find yourself doing math with time and date values, you need to stop yourself and find the right API in the language at hand. If you just need a HH:MM:SS-type response, you'll be better off with `DateUtils.formatElapsedTime`... – dovetalk Mar 12 '20 at 21:37
  • @dovetalk That can definitely be useful, and was added as a separate answer [several years ago](https://stackoverflow.com/a/33105053/752320). – Geobits Mar 13 '20 at 20:07
  • @Geobits, yes, and thanks for linking to it. I spammed many of the "solutions" here with that comment to raise awareness to less experienced developers that are likely to be tempted to roll-their-own. There are some domains where that is generally a bad idea. Time arithmetic is one – dovetalk Apr 04 '20 at 15:34
  • @dovetalk In general yes, but seconds/minutes are mostly safer than days/years by a long shot. As usual, a lot of ways to do a simple thing. – Geobits Apr 06 '20 at 15:19
  • this should be the accepted answer as it is cleaner and the hours calculation will show the actual total hours instead of a % mod value of hours. – D-Klotz Oct 16 '20 at 22:00
108

DateUtils.formatElapsedTime(long), formats an elapsed time in the form "MM:SS" or "H:MM:SS" . It returns the String you are looking for. You can find the documentation here

Magnus
  • 17,157
  • 19
  • 104
  • 189
Blackbelt
  • 156,034
  • 29
  • 297
  • 305
73

You should have more luck with

hours = roundThreeCalc.divide(var3600, BigDecimal.ROUND_FLOOR);
myremainder = roundThreeCalc.remainder(var3600);
minutes = myremainder.divide(var60, BigDecimal.ROUND_FLOOR);
seconds = myremainder.remainder(var60);

This will drop the decimal values after each division.

Edit: If that didn't work, try this. (I just wrote and tested it)

public static int[] splitToComponentTimes(BigDecimal biggy)
{
    long longVal = biggy.longValue();
    int hours = (int) longVal / 3600;
    int remainder = (int) longVal - hours * 3600;
    int mins = remainder / 60;
    remainder = remainder - mins * 60;
    int secs = remainder;

    int[] ints = {hours , mins , secs};
    return ints;
}
Haphazard
  • 10,900
  • 6
  • 43
  • 55
  • 7
    This solution is more graceful: http://stackoverflow.com/questions/625433/how-to-convert-milliseconds-to-x-mins-x-seconds-in-java – Alex Kucherenko Oct 05 '12 at 12:56
  • @AlexKucherenko except that solution works with milliseconds – Bob Jan 12 '17 at 07:37
  • 1
    @Mikhail TimeUnit.#### will allow you to do it with any unit of time. – Amir Omidi Apr 04 '18 at 07:36
  • 2
    Whenever you find yourself doing math with time and date values, you need to stop yourself and find the right API in the language at hand. If you just need a HH:MM:SS-type response, you'll be better off with `DateUtils.formatElapsedTime`... – dovetalk Mar 12 '20 at 21:37
36

Something really helpful in Java 8

import java.time.LocalTime;

private String ConvertSecondToHHMMSSString(int nSecondTime) {
    return LocalTime.MIN.plusSeconds(nSecondTime).toString();
}
Epicurist
  • 903
  • 11
  • 17
30

Here is the working code:

private String getDurationString(int seconds) {

    int hours = seconds / 3600;
    int minutes = (seconds % 3600) / 60;
    seconds = seconds % 60;

    return twoDigitString(hours) + " : " + twoDigitString(minutes) + " : " + twoDigitString(seconds);
}

private String twoDigitString(int number) {

    if (number == 0) {
        return "00";
    }

    if (number / 10 == 0) {
        return "0" + number;
    }

    return String.valueOf(number);
}
Alan Moore
  • 6,525
  • 6
  • 55
  • 68
Rahim
  • 918
  • 1
  • 12
  • 23
  • 3
    I like this answer but you need to change '% 10' to '/ 10' – Hakem Zaied Jan 15 '13 at 21:04
  • Whenever you find yourself doing math with time and date values, you need to stop yourself and find the right API in the language at hand. If you just need a HH:MM:SS-type response, you'll be better off with `DateUtils.formatElapsedTime`... – dovetalk Mar 12 '20 at 21:37
25

I prefer java's built in TimeUnit library

long seconds = TimeUnit.MINUTES.toSeconds(8);
Ajji
  • 3,068
  • 2
  • 30
  • 31
14
private String ConvertSecondToHHMMString(int secondtTime)
{
  TimeZone tz = TimeZone.getTimeZone("UTC");
  SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
  df.setTimeZone(tz);
  String time = df.format(new Date(secondtTime*1000L));

  return time;

}
Epicurist
  • 903
  • 11
  • 17
SKULL
  • 885
  • 8
  • 15
11

If you want the units h, min and sec for a duration you can use this:

public static String convertSeconds(int seconds) {
    int h = seconds/ 3600;
    int m = (seconds % 3600) / 60;
    int s = seconds % 60;
    String sh = (h > 0 ? String.valueOf(h) + " " + "h" : "");
    String sm = (m < 10 && m > 0 && h > 0 ? "0" : "") + (m > 0 ? (h > 0 && s == 0 ? String.valueOf(m) : String.valueOf(m) + " " + "min") : "");
    String ss = (s == 0 && (h > 0 || m > 0) ? "" : (s < 10 && (h > 0 || m > 0) ? "0" : "") + String.valueOf(s) + " " + "sec");
    return sh + (h > 0 ? " " : "") + sm + (m > 0 ? " " : "") + ss;
}

int seconds = 3661;
String duration = convertSeconds(seconds);

That's a lot of conditional operators. The method will return those strings:

0    -> 0 sec
5    -> 5 sec
60   -> 1 min
65   -> 1 min 05 sec
3600 -> 1 h
3601 -> 1 h 01 sec
3660 -> 1 h 01
3661 -> 1 h 01 min 01 sec
108000 -> 30 h
Sachin Tanpure
  • 1,068
  • 11
  • 12
Nicolas
  • 6,611
  • 3
  • 29
  • 73
11

This is my simple solution:

String secToTime(int sec) {
    int seconds = sec % 60;
    int minutes = sec / 60;
    if (minutes >= 60) {
        int hours = minutes / 60;
        minutes %= 60;
        if( hours >= 24) {
            int days = hours / 24;
            return String.format("%d days %02d:%02d:%02d", days,hours%24, minutes, seconds);
        }
        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    return String.format("00:%02d:%02d", minutes, seconds);
}

Test Results:

Result: 00:00:36 - 36
Result: 01:00:07 - 3607
Result: 6313 days 12:39:05 - 545488745
Shohan Ahmed Sijan
  • 4,391
  • 1
  • 33
  • 39
5

I like to keep things simple therefore:

    int tot_seconds = 5000;
    int hours = tot_seconds / 3600;
    int minutes = (tot_seconds % 3600) / 60;
    int seconds = tot_seconds % 60;

    String timeString = String.format("%02d Hour %02d Minutes %02d Seconds ", hours, minutes, seconds);

    System.out.println(timeString);

The result will be: 01 Hour 23 Minutes 20 Seconds

Nello
  • 141
  • 4
  • 15
5

Duration from java.time

    BigDecimal secondsValue = BigDecimal.valueOf(4953);
    if (secondsValue.compareTo(BigDecimal.valueOf(Long.MAX_VALUE)) > 0) {
        System.out.println("Seconds value " + secondsValue + " is out of range");
    } else {
        Duration dur = Duration.ofSeconds(secondsValue.longValueExact());
        long hours = dur.toHours();
        int minutes = dur.toMinutesPart();
        int seconds = dur.toSecondsPart();

        System.out.format("%d hours %d minutes %d seconds%n", hours, minutes, seconds);
    }

Output from this snippet is:

1 hours 22 minutes 33 seconds

If there had been a non-zero fraction of second in the BigDecimal this code would not have worked as it stands, but you may be able to modify it. The code works in Java 9 and later. In Java 8 the conversion from Duration into hours minutes and seconds is a bit more wordy, see the link at the bottom for how. I am leaving to you to choose the correct singular or plural form of the words (hour or hours, etc.).

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
4

A nice and easy way to do it using GregorianCalendar

Import these into the project:

import java.util.GregorianCalendar;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Scanner;

And then:

Scanner s = new Scanner(System.in);

System.out.println("Seconds: ");
int secs = s.nextInt();

GregorianCalendar cal = new GregorianCalendar(0,0,0,0,0,secs);
Date dNow = cal.getTime();
SimpleDateFormat ft = new SimpleDateFormat("HH 'hours' mm 'minutes' ss 'seconds'");
System.out.println("Your time: " + ft.format(dNow));
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
4

This Code Is working Fine :

txtTimer.setText(String.format("%02d:%02d:%02d",(SecondsCounter/3600), ((SecondsCounter % 3600)/60), (SecondsCounter % 60)));
4

for just minutes and seconds use this

String.format("%02d:%02d", (seconds / 3600 * 60 + ((seconds % 3600) / 60)), (seconds % 60))
Asthme
  • 5,163
  • 6
  • 47
  • 65
4

With Java 8, you can easily achieve time in String format from long seconds like,

LocalTime.ofSecondOfDay(86399L)

Here, given value is max allowed to convert (upto 24 hours) and result will be

23:59:59

Pros : 1) No need to convert manually and to append 0 for single digit

Cons : work only for up to 24 hours

Chirag Shah
  • 353
  • 1
  • 13
2

Here's my function to address the problem:

public static String getConvertedTime(double time){

    double h,m,s,mil;

    mil = time % 1000;
    s = time/1000;
    m = s/60;
    h = m/60;
    s = s % 60;
    m = m % 60;
    h = h % 24;

    return ((int)h < 10 ? "0"+String.valueOf((int)h) : String.valueOf((int)h))+":"+((int)m < 10 ? "0"+String.valueOf((int)m) : String.valueOf((int)m))
            +":"+((int)s < 10 ? "0"+String.valueOf((int)s) : String.valueOf((int)s))
            +":"+((int)mil > 100 ? String.valueOf((int)mil) : (int)mil > 9 ? "0"+String.valueOf((int)mil) : "00"+String.valueOf((int)mil));
}
Chris Rae
  • 5,627
  • 2
  • 36
  • 51
leokash
  • 200
  • 1
  • 6
2

I use this:

 public String SEG2HOR( long lnValue) {     //OK
        String lcStr = "00:00:00";
        String lcSign = (lnValue>=0 ? " " : "-");
        lnValue = lnValue * (lnValue>=0 ? 1 : -1); 

        if (lnValue>0) {                
            long lnHor  = (lnValue/3600);
            long lnHor1 = (lnValue % 3600);
            long lnMin  = (lnHor1/60);
            long lnSec  = (lnHor1 % 60);            

                        lcStr = lcSign + ( lnHor < 10 ? "0": "") + String.valueOf(lnHor) +":"+
                              ( lnMin < 10 ? "0": "") + String.valueOf(lnMin) +":"+
                              ( lnSec < 10 ? "0": "") + String.valueOf(lnSec) ;
        }

        return lcStr;           
    }
animuson
  • 53,861
  • 28
  • 137
  • 147
cesin
  • 99
  • 5
2

I know this is pretty old but in java 8:

LocalTime.MIN.plusSeconds(120).format(DateTimeFormatter.ISO_LOCAL_TIME)
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
Causteau
  • 117
  • 1
  • 10
1

I use this in python to convert a float representing seconds to hours, minutes, seconds, and microseconds. It's reasonably elegant and is handy for converting to a datetime type via strptime to convert. It could also be easily extended to longer intervals (weeks, months, etc.) if needed.

    def sectohmsus(seconds):
        x = seconds
        hmsus = []
        for i in [3600, 60, 1]:  # seconds in a hour, minute, and second
            hmsus.append(int(x / i))
            x %= i
        hmsus.append(int(round(x * 1000000)))  # microseconds
        return hmsus  # hours, minutes, seconds, microsecond
rtphokie
  • 609
  • 1
  • 6
  • 14
1

i have tried the best way and less code but may be it is little bit difficult to understand how i wrote my code but if you good at maths it is so easy

import java.util.Scanner;

class hours {

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    double s;


    System.out.println("how many second you have ");
    s =input.nextInt();



     double h=s/3600;
     int h2=(int)h;

     double h_h2=h-h2;
     double m=h_h2*60;
     int m1=(int)m;

     double m_m1=m-m1;
     double m_m1s=m_m1*60;






     System.out.println(h2+" hours:"+m1+" Minutes:"+Math.round(m_m1s)+" seconds");





}

}

more over it is accurate !

0

Tough there are yet many correct answers and an accepted one, if you want a more handmade and systematized way to do this, I suggest something like this:

/**
 * Factors for converting seconds in minutes, minutes in hours, etc.
 */
private static int[] FACTORS = new int[] {
    60, 60, 24, 7
};

/**
 * Names of each time unit.
 * The length of this array needs to be FACTORS.length + 1.
 * The last one is the name of the remainder after
 * obtaining each component.
 */
private static String[] NAMES = new String[] {
    "second", "minute", "hour", "day", "week"
};

/**
 * Checks if quantity is 1 in order to use or not the plural.
 */
private static String quantityToString(int quantity, String name) {
    if (quantity == 1) {
        return String.format("%d %s", quantity, name);
    }
    return String.format("%d %ss", quantity, name);
}

/**
 * The seconds to String method.
 */
private static String secondsToString(int seconds) {
    List<String> components = new ArrayList<>();

    /**
     * Obtains each component and stores only if is not 0.
     */
    for (int i = 0; i < FACTORS.length; i++) {
        int component = seconds % FACTORS[i];
        seconds /= FACTORS[i];
        if (component != 0) {
            components.add(quantityToString(component, NAMES[i]));
        }
    }
    
    /**
     * The remainder is the last component.
     */
    if (seconds != 0) {
        components.add(quantityToString(seconds, NAMES[FACTORS.length]));
    }
    
    /**
     * We have the non-0 components in reversed order.
     * This could be extracted to another method.
     */
    StringBuilder builder = new StringBuilder();
    for (int i = components.size() - 1; i >= 0; i--) {
        if (i == 0 && components.size() > 1) {
            builder.append(" and ");
        } else if (builder.length() > 0) {
            builder.append(", ");
        }
        builder.append(components.get(i));
    }
    
    return builder.toString();
}

The result is as following:

System.out.println(secondsToString(5_000_000)); // 8 weeks, 1 day, 20 hours, 53 minutes and 20 seconds
System.out.println(secondsToString(500_000)); // 5 days, 18 hours, 53 minutes and 20 seconds
System.out.println(secondsToString(60*60*24)); // 1 day
System.out.println(secondsToString(2*60*60*24 + 3*60)); // 2 days and 3 minutes
System.out.println(secondsToString(60*60*24 + 3 * 60 * 60 + 53)); // 1 day, 3 hours and 53 seconds
Alfredo Tostón
  • 327
  • 2
  • 12
0

You can get this done easily using method overloading.

Here's a code I wrote to convert seconds to hours, minutes and seconds format.

public class SecondsAndMinutes {

    public static void main(String[] args) {

        String finalOutput = getDurationString(-3666);

        System.out.println(finalOutput);

    }

    public static String getDurationString(int seconds) {
         if(seconds <= 0) {
             return "Add a value bigger than zero.";
         }else {

             int hours = seconds / (60*60);
             int remainingOneSeconds = seconds % (60*60);
             int minutes = remainingOneSeconds / 60;
             int remainingSeconds = remainingOneSeconds % 60;

             String x = Integer.toString(hours);

             return x+"h " + getDurationString(minutes, remainingSeconds);
         }
    }

    public static String getDurationString(int minutes, int seconds) {
        if(seconds <= 0 && seconds > 59) {
            return "Seconds needs to be within 1 to 59";
        }else {

            String y = Integer.toString(minutes);
            String z = Integer.toString(seconds);

            return y+"m "+z+"s";
        }

    }
}
SasithM
  • 39
  • 2