Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to format an elapsed time interval in hh:mm:ss.SSS format in Java?

People also ask

How do you represent HH MM SS in Java?

SimpleDateFormat(“hh:mm:ss a”) in Java.

How do you convert milliseconds to HH MM SS in Java?

format("%02d:%02d:%02d", hours, minutes, seconds); System. out. println(hhmmss);

How do you convert milliseconds to hours minutes seconds in Java?

Convert Milliseconds to minutes using the formula: minutes = (milliseconds/1000)/60). Convert Milliseconds to seconds using the formula: seconds = (milliseconds/1000)%60). The print output from Milliseconds to minutes and seconds.


Support for what you want to do is built in to the latest JDKs with a little known class called TimeUnit.

What you want to use is java.util.concurrent.TimeUnit to work with intervals.

SimpleDateFormat does just what it sounds like it does, it formats instances of java.util.Date, or in your case it converts the long value into the context of a java.util.Date and it doesn't know what to do with intervals which is what you apparently are working with.

You can easily do this without having to resort to external libraries like JodaTime.

import java.util.concurrent.TimeUnit;

public class Main
{        
    private static String formatInterval(final long l)
    {
        final long hr = TimeUnit.MILLISECONDS.toHours(l);
        final long min = TimeUnit.MILLISECONDS.toMinutes(l - TimeUnit.HOURS.toMillis(hr));
        final long sec = TimeUnit.MILLISECONDS.toSeconds(l - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min));
        final long ms = TimeUnit.MILLISECONDS.toMillis(l - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min) - TimeUnit.SECONDS.toMillis(sec));
        return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
    }

    public static void main(final String[] args)
    {
        System.out.println(formatInterval(Long.parseLong(args[0])));
    }
}

The output will be formatted something like this

13:00:00.000

A shorter way to do this is to use the DurationFormatUtils class in Apache Commons Lang:

public static String formatTime(long millis) {
    return DurationFormatUtils.formatDuration(millis, "HH:mm:ss.S");
}

Why not this ?

public static String GetFormattedInterval(final long ms) {
    long millis = ms % 1000;
    long x = ms / 1000;
    long seconds = x % 60;
    x /= 60;
    long minutes = x % 60;
    x /= 60;
    long hours = x % 24;

    return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis);
}

Here's how I've done it, using only the standard JDK (this will work as far back as Java 1.1 by changing StringBuilder back to StringBuffer):

static public String formatMillis(long val) {
    StringBuilder                       buf=new StringBuilder(20);
    String                              sgn="";

    if(val<0) { sgn="-"; val=Math.abs(val); }

    append(buf,sgn,0,(val/3600000)); val%=3600000;
    append(buf,":",2,(val/  60000)); val%=  60000;
    append(buf,":",2,(val/   1000)); val%=   1000;
    append(buf,".",3,(val        ));
    return buf.toString();
    }

/** Append a right-aligned and zero-padded numeric value to a `StringBuilder`. */
static private void append(StringBuilder tgt, String pfx, int dgt, long val) {
    tgt.append(pfx);
    if(dgt>1) {
        int pad=(dgt-1);
        for(long xa=val; xa>9 && pad>0; xa/=10) { pad--;           }
        for(int  xa=0;   xa<pad;        xa++  ) { tgt.append('0'); }
        }
    tgt.append(val);
    }

This is the first bit of Joda work I've done where it seemed more tedious than the JDK support. A Joda implementation for the requested format (making a few assumptions about zero fields) is:

public void printDuration(long milliSecs)
{
    PeriodFormatter formatter = new PeriodFormatterBuilder()
        .printZeroIfSupported()
        .appendHours()
        .appendSeparator(":")
        .minimumPrintedDigits(2)
        .appendMinutes()
        .appendSeparator(":")
        .appendSecondsWithMillis()
        .toFormatter();

    System.out.println(formatter.print(new Period(milliSecs)));
}

Reviewing the other answers, I came up with this function...

public static String formatInterval(final long interval, boolean millisecs )
{
    final long hr = TimeUnit.MILLISECONDS.toHours(interval);
    final long min = TimeUnit.MILLISECONDS.toMinutes(interval) %60;
    final long sec = TimeUnit.MILLISECONDS.toSeconds(interval) %60;
    final long ms = TimeUnit.MILLISECONDS.toMillis(interval) %1000;
    if( millisecs ) {
        return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
    } else {
        return String.format("%02d:%02d:%02d", hr, min, sec );
    }
}