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

最好的方法是什么?


当前回答

我的简单计算是:

String millisecToTime(int millisec) {
    int sec = millisec/1000;
    int second = sec % 60;
    int minute = sec / 60;
    if (minute >= 60) {
        int hour = minute / 60;
        minute %= 60;
        return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second);
    }
    return minute + ":" + (second < 10 ? "0" + second : second);
}

快乐编码:)

其他回答

使用java。Java 8中的时间包:

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

输出为ISO 8601 Duration格式:pt1m3.53s(1分3.553秒)。

只是为了补充更多信息 如果你想格式化为:HH:mm:ss

0 <= HH <= infinite

0 <= mm < 60

0 <= ss < 60

用这个:

int h = (int) ((startTimeInMillis / 1000) / 3600);
int m = (int) (((startTimeInMillis / 1000) / 60) % 60);
int s = (int) ((startTimeInMillis / 1000) % 60);

我只是现在有这个问题,并解决了这个问题

使用java.util.concurrent.TimeUnit类:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);

注意:TimeUnit是Java 1.5规范的一部分,但是toMinutes是在Java 1.6中添加的。

为0-9的值添加前导零,只需执行以下操作:

String.format("%02d min, %02d sec", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);

如果TimeUnit或toMinutes不受支持(例如在API版本9之前的Android上),使用以下公式:

int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
//etc...

我在另一个答案中提到了这一点,但你可以这样做:

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
    long diffInMillies = date2.getTime() - date1.getTime();
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;
    for ( TimeUnit unit : units ) {
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;
        result.put(unit,diff);
    }
    return result;
}

输出类似Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0},单位是有序的。

由您决定如何根据目标语言环境对这些数据进行国际化。

最短的解决方案:

这可能是最短的一个,也涉及到时区。

System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());

输出例如:

00:18:32

解释:

%tT是24小时时钟格式为%tH:%tM:%tS的时间。

%tT也接受长时间作为输入,因此不需要创建Date。Printf()将简单地以毫秒为单位打印指定的时间,但在当前时区中,因此我们必须减去当前时区的原始偏移量,以便0毫秒将是0小时,而不是当前时区的时间偏移值。

注意#1:如果你需要一个字符串形式的结果,你可以这样得到它:

String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());

注意#2:只有当millis小于一天时,才会给出正确的结果,因为一天部分不包括在输出中。