如何在Java中将毫秒转换为"X分钟,X秒钟"?

630
我想在我的程序中记录用户开始某项任务时的时间,可以使用System.currentTimeMillis()。当用户完成任务后,我将从start变量中减去当前的System.currentTimeMillis(),然后我想以人类可读的格式显示已经过去的时间,例如 "XX小时,XX分钟,XX秒" 或者 "XX分钟,XX秒",因为不太可能需要一个小时的时间。
最佳方法是什么?

5
如果时间超过一个小时,你仍然可以打印出类似于“90分53秒”的内容。 - Peter Lawrey
30个回答

3
这个答案与其他一些答案类似。然而,我认为这将是有益的,因为与其他答案不同,它会删除任何额外的逗号或空格并处理缩写。
/**
 * Converts milliseconds to "x days, x hours, x mins, x secs"
 * 
 * @param millis
 *            The milliseconds
 * @param longFormat
 *            {@code true} to use "seconds" and "minutes" instead of "secs" and "mins"
 * @return A string representing how long in days/hours/minutes/seconds millis is.
 */
public static String millisToString(long millis, boolean longFormat) {
    if (millis < 1000) {
        return String.format("0 %s", longFormat ? "seconds" : "secs");
    }
    String[] units = {
            "day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec"
    };
    long[] times = new long[4];
    times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS);
    times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS);
    times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES);
    times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
    StringBuilder s = new StringBuilder();
    for (int i = 0; i < 4; i++) {
        if (times[i] > 0) {
            s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s"));
        }
    }
    return s.toString().substring(0, s.length() - 2);
}

/**
 * Converts milliseconds to "x days, x hours, x mins, x secs"
 * 
 * @param millis
 *            The milliseconds
 * @return A string representing how long in days/hours/mins/secs millis is.
 */
public static String millisToString(long millis) {
    return millisToString(millis, false);
}

3

对于正确的字符串(如“1小时,3秒”,“3分钟”而不是“0小时,0分钟,3秒”),我编写了以下代码:

int seconds = (int)(millis / 1000) % 60 ;
int minutes = (int)((millis / (1000*60)) % 60);
int hours = (int)((millis / (1000*60*60)) % 24);
int days = (int)((millis / (1000*60*60*24)) % 365);
int years = (int)(millis / 1000*60*60*24*365);

ArrayList<String> timeArray = new ArrayList<String>();

if(years > 0)   
    timeArray.add(String.valueOf(years)   + "y");

if(days > 0)    
    timeArray.add(String.valueOf(days) + "d");

if(hours>0)   
    timeArray.add(String.valueOf(hours) + "h");

if(minutes>0) 
    timeArray.add(String.valueOf(minutes) + "min");

if(seconds>0) 
    timeArray.add(String.valueOf(seconds) + "sec");

String time = "";
for (int i = 0; i < timeArray.size(); i++) 
{
    time = time + timeArray.get(i);
    if (i != timeArray.size() - 1)
        time = time + ", ";
}

if (time == "")
  time = "0 sec";

3

存在一个问题。当毫秒数为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);
}

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

如果您知道时差将小于一小时,则可以使用以下代码:

    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。

2

我在另一个答案中已经讲过这个问题,但是你可以这样做:

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},其中单位已按顺序排列。

您需要根据目标语言环境来确定如何国际化此数据。


2
这个话题已经被充分讨论,我想分享我的函数,也许你可以使用它们而不是导入整个库。
    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);
    }


1
使用 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));

1
我修改了 @MyKuLLSKI 的答案并添加了复数支持。我去掉了秒数,因为我不需要它们,但如果您需要,可以随时重新添加。
public static String intervalToHumanReadableTime(int intervalMins) {

    if(intervalMins <= 0) {
        return "0";
    } else {

        long intervalMs = intervalMins * 60 * 1000;

        long days = TimeUnit.MILLISECONDS.toDays(intervalMs);
        intervalMs -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(intervalMs);
        intervalMs -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs);

        StringBuilder sb = new StringBuilder(12);

        if (days >= 1) {
            sb.append(days).append(" day").append(pluralize(days)).append(", ");
        }

        if (hours >= 1) {
            sb.append(hours).append(" hour").append(pluralize(hours)).append(", ");
        }

        if (minutes >= 1) {
            sb.append(minutes).append(" minute").append(pluralize(minutes));
        } else {
            sb.delete(sb.length()-2, sb.length()-1);
        }

        return(sb.toString());          

    }

}

public static String pluralize(long val) {
    return (Math.round(val) > 1 ? "s" : "");
}

int intervalMins vs long millis - Kiquenet

0
@Brent Writes Code的代码再次进行了澄清:


    public static String humanReadableTimeSpent(long millis) {
        if (millis < 0) {
            throw new IllegalArgumentException("Something is not right, time can't be negative!");
        }

        long days = TimeUnit.MILLISECONDS.toDays(millis);
        millis -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(millis);
        millis -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
        millis -= TimeUnit.MINUTES.toMillis(minutes);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
        millis -= TimeUnit.SECONDS.toMillis(seconds);
        long millisecs = TimeUnit.MILLISECONDS.toMillis(millis);

        StringBuilder sb = new StringBuilder(64);
        if (days > 0) {
            sb.append(days);
            sb.append(" days ");
        }
        if (hours > 0) {
            sb.append(hours);
            sb.append(" hrs ");
        }
        if (minutes > 0) {
            sb.append(minutes);
            sb.append(" mins ");
        }
        if (seconds > 0) {
            sb.append(seconds);
            sb.append(" secs ");
        }
        if (millisecs > 0) {
            sb.append(millisecs);
            sb.append(" mills");
        }

        return (sb.toString());
    }


并按照以下方式进行呼叫:
humanReadableTimeSpent(endTimeMills - startTimeMills)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接