Search code examples
javatimesimpledateformat

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


I'm making a stop watch where I'm using Java's SimpleDateFormat to convert the number of milliseconds into a nice "hh:mm:ss:SSS" format. The problem is the hours field always has some random number in it. Here's the code I'm using:

public static String formatTime(long millis) {
    SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss.SSS");

    String strDate = sdf.format(millis);
    return strDate;
}

If I take off the hh part then it works fine. Otherwise in the hh part it'll display something random like "07" even if the argument passed in (number of milliseconds) is zero.

I don't know much about the SimpleDateFormat class though. Thanks for any help.


Solution

  • 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);
        }