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

最好的方法是什么?


当前回答

使用java . util . concurrent。TimeUnit,使用这个简单的方法:

private static long timeDiff(Date date, Date date2, TimeUnit unit) {
    long milliDiff=date2.getTime()-date.getTime();
    long unitDiff = unit.convert(milliDiff, TimeUnit.MILLISECONDS);
    return unitDiff; 
}

例如:

SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");  
Date firstDate = sdf.parse("06/24/2017 04:30:00");
Date secondDate = sdf.parse("07/24/2017 05:00:15");
Date thirdDate = sdf.parse("06/24/2017 06:00:15");

System.out.println("days difference: "+timeDiff(firstDate,secondDate,TimeUnit.DAYS));
System.out.println("hours difference: "+timeDiff(firstDate,thirdDate,TimeUnit.HOURS));
System.out.println("minutes difference: "+timeDiff(firstDate,thirdDate,TimeUnit.MINUTES));
System.out.println("seconds difference: "+timeDiff(firstDate,thirdDate,TimeUnit.SECONDS));

其他回答

乔达时间

使用Joda-Time:

DateTime startTime = new DateTime();

// do something

DateTime endTime = new DateTime();
Duration duration = new Duration(startTime, endTime);
Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
System.out.println(PeriodFormat.getDefault().print(period));

这个主题已经被很好地覆盖了,我只是想分享我的函数,也许你可以使用这些函数,而不是导入整个库。

    public long getSeconds(ms) {
        return (ms/1000%60);
    }
    public long getMinutes(ms) {
        return (ms/(1000*60)%60);
    }
    public long getHours(ms) {
        return ((ms/(1000*60*60))%24);
    }

我不会为此引入额外的依赖项(毕竟,除法并不那么难),但如果您无论如何都在使用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())

这在Java 9中更容易:

    Duration elapsedTime = Duration.ofMillis(millisDiff );
    String humanReadableElapsedTime = String.format(
            "%d hours, %d mins, %d seconds",
            elapsedTime.toHours(),
            elapsedTime.toMinutesPart(),
            elapsedTime.toSecondsPart());

这将生成像0小时39分9秒这样的字符串。

如果你想在格式化前舍入整秒:

    elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);

如果小时数为0,则省略:

    long hours = elapsedTime.toHours();
    String humanReadableElapsedTime;
    if (hours == 0) {
        humanReadableElapsedTime = String.format(
                "%d mins, %d seconds",
                elapsedTime.toMinutesPart(),
                elapsedTime.toSecondsPart());

    } else {
        humanReadableElapsedTime = String.format(
                "%d hours, %d mins, %d seconds",
                hours,
                elapsedTime.toMinutesPart(),
                elapsedTime.toSecondsPart());
    }

现在我们有39分9秒。

要打印前导0的分钟和秒,使它们始终是两个数字,只需在相关的格式说明符中插入02,如下所示:

    String humanReadableElapsedTime = String.format(
            "%d hours, %02d mins, %02d seconds",
            elapsedTime.toHours(),
            elapsedTime.toMinutesPart(),
            elapsedTime.toSecondsPart());

现在我们有0小时39分09秒。

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

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