如何在Java中格式化hh:mm:ss.SSS格式的经过时间间隔?

JDS*_*JDS 36 java time simpledateformat

我正在制作一个秒表,我正在使用Java的SimpleDateFormat将毫秒数转换成一个漂亮的"hh:mm:ss:SSS"格式.问题是小时字段总是有一些随机数.这是我正在使用的代码:

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

    String strDate = sdf.format(millis);
    return strDate;
}
Run Code Online (Sandbox Code Playgroud)

如果我脱掉hh部分那么它工作正常.否则在hh部分,即使传入的参数(毫秒数)为零,它也会显示随机的内容,如"07".

我对SimpleDateFormat类知之甚少.谢谢你的帮助.

小智 70

支持您想要做的事情内置于最新的JDK中,并且有一个名为的已知类TimeUnit.

您想要使用的是java.util.concurrent.TimeUnit来处理间隔.

SimpleDateFormat做它听起来像是什么,它格式化实例java.util.Date,或者在你的情况下它将long值转换为a的上下文,java.util.Date它不知道如何处理你显然正在使用的间隔.

您可以轻松地执行此操作,而无需使用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])));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出将格式化为这样

13:00:00.000
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案中的'l'(ell)看起来非常像一个.我会使用类似mstime的东西来表示该变量. (4认同)
  • 另外,我喜欢它,但我不确定它是否比写作更漂亮:long elapsedTimeSeconds = elapsedTimeMillis / 1000; String.format("%02d:%02d:%02d.%03d", elapsedTimeSeconds / 3600, elapsedTimeSeconds % 3600) / 60, (elapsedTimeSeconds % 60), elapsedTimeMillis % 1000); (2认同)

小智 28

更简单的方法是在Apache Commons Lang中使用DurationFormatUtils类:

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


Jef*_* T. 7

为什么不呢?

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);
}
Run Code Online (Sandbox Code Playgroud)


Law*_*Dol 6

这就是我如何使用标准JDK完成它(这可以通过改StringBuilder回到Java 1.1 来工作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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 这不是解决这个问题的惯用Java方法.`SimpleDateFormat`和`TimeUnit`内置于标准库中以解决这些问题,而不包括兆字节的第三方库或自己编写所有数学和字符串操作代码.如果没有其他原因,那就是`SimpleDateFormat`透明地处理时区信息. (6认同)
  • @Jarrod:首先,对于*逝去的*时间,Timezone是不相关的,SimpleDateFormat不是正确的类,第二,如果你卡住了较旧的VM TimeUnit不是一个选项. (3认同)

Ed *_*aub 5

这是Joda工作的第一部分,我已经完成了比JDK支持更繁琐的工作.请求格式的Joda实现(对零字段做出一些假设)是:

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)));
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,[*Joda-Time*](http://www.joda.org/joda-time/) 项目现在处于[维护模式](https://en.wikipedia.org/wiki/Maintenance_mode),建议迁移到 [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) 类。请参阅 [Oracle 教程](https://docs.oracle.com/javase/tutorial/datetime/TOC.html)。 (2认同)

mks*_*eve 5

回顾其他答案,我想出了这个功能......

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 );
    }
}
Run Code Online (Sandbox Code Playgroud)