我想使用System.currentTimeMillis()记录用户在程序中开始某项操作时的时间。当他完成时,我将从start变量中减去当前的System.currentTimeMillis(),并且我希望使用人类可读的格式显示他们所经过的时间,例如“XX小时,XX分钟,XX秒”,甚至“XX分钟,XX秒”,因为它不太可能花费某人一个小时。

最好的方法是什么?


当前回答

如果你知道时间差将小于一个小时,那么你可以使用以下代码:

    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();

    c2.add(Calendar.MINUTE, 51);

    long diff = c2.getTimeInMillis() - c1.getTimeInMillis();

    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR, 0);
    c2.set(Calendar.SECOND, 0);

    DateFormat df = new SimpleDateFormat("mm:ss");
    long diff1 = c2.getTimeInMillis() + diff;
    System.out.println(df.format(new Date(diff1)));

结果是:51:00

其他回答

有个问题。当毫秒为59999时,实际上是1分钟,但它将被计算为59秒,损失了999毫秒。

以下是根据之前的答案修改后的版本,可以解决这个损失:

public static String formatTime(long millis) {
    long seconds = Math.round((double) millis / 1000);
    long hours = TimeUnit.SECONDS.toHours(seconds);
    if (hours > 0)
        seconds -= TimeUnit.HOURS.toSeconds(hours);
    long minutes = seconds > 0 ? TimeUnit.SECONDS.toMinutes(seconds) : 0;
    if (minutes > 0)
        seconds -= TimeUnit.MINUTES.toSeconds(minutes);
    return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
}

我不会为此引入额外的依赖项(毕竟,除法并不那么难),但如果您无论如何都在使用Commons Lang,还有DurationFormatUtils。

用法示例(从这里改编):

import org.apache.commons.lang3.time.DurationFormatUtils

public String getAge(long value) {
    long currentTime = System.currentTimeMillis();
    long age = currentTime - value;
    String ageString = DurationFormatUtils.formatDuration(age, "d") + "d";
    if ("0d".equals(ageString)) {
        ageString = DurationFormatUtils.formatDuration(age, "H") + "h";
        if ("0h".equals(ageString)) {
            ageString = DurationFormatUtils.formatDuration(age, "m") + "m";
            if ("0m".equals(ageString)) {
                ageString = DurationFormatUtils.formatDuration(age, "s") + "s";
                if ("0s".equals(ageString)) {
                    ageString = age + "ms";
                }
            }
        }
    }
    return ageString;
}   

例子:

long lastTime = System.currentTimeMillis() - 2000;
System.out.println("Elapsed time: " + getAge(lastTime)); 

//Output: 2s

注意:从两个LocalDateTime对象中获取millis可以使用:

long age = ChronoUnit.MILLIS.between(initTime, LocalDateTime.now())

适用于API 9以下的Android

(String.format("%d hr %d min, %d sec", millis/(1000*60*60), (millis%(1000*60*60))/(1000*60), ((millis%(1000*60*60))%(1000*60))/1000)) 

对于一小时以内的小时间,我更喜欢:

long millis = ...

System.out.printf("%1$TM:%1$TS", millis);
// or
String str = String.format("%1$TM:%1$TS", millis);

对于较长的间隔:

private static final long HOUR = TimeUnit.HOURS.toMillis(1);
...
if (millis < HOUR) {
    System.out.printf("%1$TM:%1$TS%n", millis);
} else {
    System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR);
}

回顾@brent-nash的贡献,我们可以使用模函数代替减法并使用String。结果字符串的格式方法:

  /**
   * Convert a millisecond duration to a string format
   * 
   * @param millis A duration to convert to a string form
   * @return A string of the form "X Days Y Hours Z Minutes A Seconds B Milliseconds".
   */
   public static String getDurationBreakdown(long millis) {
       if (millis < 0) {
          throw new IllegalArgumentException("Duration must be greater than zero!");
       }

       long days = TimeUnit.MILLISECONDS.toDays(millis);
       long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24;
       long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
       long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
       long milliseconds = millis % 1000;

       return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds",
                            days, hours, minutes, seconds, milliseconds);
   }