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

Posted

技术标签:

【中文标题】如何在 Java 中将毫秒转换为“X 分钟,x 秒”?【英文标题】:How to convert Milliseconds to "X mins, x seconds" in Java? 【发布时间】:2010-10-12 03:28:36 【问题描述】:

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

最好的方法是什么?

【问题讨论】:

如果他们需要一个多小时,你仍然可以打印类似的东西; 90 分 53 秒。 【参考方案1】:

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

如果 TimeUnittoMinutes 不受支持(例如在 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...

【讨论】:

int 月 =(int)((float)days / 30.4368499f); int 年 = (int)((float)days / 365.242199f); 我建议使用 mod 60 而不是减去分钟,它看起来更干净。但是,需要知道 1 分钟 = 60 秒才能做到这一点... =) @AndreasDietrich SimpleDateFormat 不适用于时差,因为它只返回纪元的日期! int hours = (int) ((milliseconds / (1000*60*60)) % 24) 这不起作用!相反,它应该是这样的int hours = (int) (milliseconds / (1000*60*60)) ; 如果有人想要视频文件的格式 (h:mm:ss):String.format("%01d:%02d:%02d", hours, minutes, seconds);【参考方案2】:

根据@siddhadev 的回答,我编写了一个函数,可以将毫秒转换为格式化字符串:

   /**
     * 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".
     */
    public static String getDurationBreakdown(long millis) 
        if(millis < 0) 
            throw new IllegalArgumentException("Duration must be greater than zero!");
        

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

        StringBuilder sb = new StringBuilder(64);
        sb.append(days);
        sb.append(" Days ");
        sb.append(hours);
        sb.append(" Hours ");
        sb.append(minutes);
        sb.append(" Minutes ");
        sb.append(seconds);
        sb.append(" Seconds");

        return(sb.toString());
    

【讨论】:

你应该在那里检查单个/多个,以避免这种情况:1 Days 1 Hours 1 Minutes 1 Seconds 我们可以使用取模函数代替减法: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; 以及 String.format 方法:return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);【参考方案3】:
long time = 1536259;

return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));

打印:

25:36:259

【讨论】:

我最喜欢上面的方法,只要它简单!由于我们正在处理时间和持续时间,我通常使用 Joda。例如,如果您有两个 DateTime,分别开始和结束:Duration dur = new Duration(start, end);long millis = dur.getMillis(); 我应该注意到 2 种使用 Joda 格式化程序的方法。您的主题的第一个变体:DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time)); 或将持续时间转换为可以使用 Joda PeriodFormatter 自动打印的期间。如果不是 ISO 年表,则转换可能会损失精度。假设由变量duration 表示的持续时间。 Period period = duration.toPeriod().normalizedStandard(PeriodType.time()); PeriodFormat.getDefault().print(period)) 输出很棒:1 秒 581 毫秒,回答了上面的主要问题。 这里有点晚了 :) 但是你不需要把 simpleDateFormat.setTimezone(TimeZone.getTimeZone("GMT")) 放在这里,除非那是你的实际时区? @OlleSöderström 这里的时区确实存在问题。但是将其设置为 GMT 或 UTC 会导致小时部分为 12 而不是 0 对于所有短于 1 小时的持续时间。 时区不是这里唯一的问题......这个答案具有误导性,可能会严重混淆 Java 新手。即使忽略多余的外括号,OP 也询问如何呈现 duration (两个时间点之间的差异,以毫秒为单位)。将该持续时间称为“时间”并将其视为自 1970 年 1 月 1 日以来的偏移量,只是为了格式化其较小的组件,这只是......错误的 imo。更重要的是,this answer 早在 3 年前就已经提出了相同的方法(有关时区问题的更多详细信息,请参见那里的 cmets)。【参考方案4】:

嗯...一秒钟有多少毫秒?在一分钟内?除法并不难。

int seconds = (int) ((milliseconds / 1000) % 60);
int minutes = (int) ((milliseconds / 1000) / 60);

这样持续数小时、数天、数周、数月、数年、数十年等等。

【讨论】:

实际上,这样做超过一个小时并不是一个好主意,因为当涉及夏令时(23 或 24 小时的天数)或闰年时,结果可能是错误的/不直观的。如果我读到“X 将在 1 年/月内发生”,我希望它是相同的日期和时间。 System.currentTimeMillis() 对 DST 免疫,因此不会因额外或缺失的时间而混淆。如果您需要显示两个特定日期之间的差异,您最好构建具有给定时间的 Date 对象并显示这两个日期之间的差异。 几周之后,它是未定义的,因为月份长度是可变的。因此,确实,您需要相对于给定的时间参考进行计算。【参考方案5】:

在 Java 8 中使用 java.time package:

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

输出为ISO 8601 Duration format:PT1M3.553S(1 分 3.553 秒)。

【讨论】:

另见How to format a duration in java? (e.g format H:MM:SS) (ANDROID) 需要 API 级别 26 @SomeoneSomewhere 对于 API 级别 26 下的 Android,请使用反向端口,请参阅 How to use ThreeTenABP in Android Project。【参考方案6】:

要么手动分区,要么使用SimpleDateFormat API。

long start = System.currentTimeMillis();
// do your work...
long elapsed = System.currentTimeMillis() - start;
DateFormat df = new SimpleDateFormat("HH 'hours', mm 'mins,' ss 'seconds'");
df.setTimeZone(TimeZone.getTimeZone("GMT+0"));
System.out.println(df.format(new Date(elapsed)));

Bombe编辑:已在 cmets 中显示这种方法仅适用于较短的持续时间(即少于一天)。

【讨论】:

哇。这是一个邪恶的、依赖时区的黑客攻击。当您的时区偏移不是 60 分钟的倍数时,它将无情地中断(我们在世界上有几个讨厌的 30 分钟偏移时区)。 此外,出于同样的原因,只要您在格式字符串中包含小时数并且不在 GMT+0 时,它就会崩溃。 我们有吗?真的吗?在哪里?不怀疑你,只是以前从未听说过 - 一些新的陷阱要考虑;-) 是的。检查 Wikipedia 上的“时区列表”,例如尼泊尔时间为 GMT+05:45。 cadrian,现在它只能在不到一天的时间内工作。小时数始终介于 0 到 23 之间,包括 0 到 23。【参考方案7】:

我不会仅仅为此而引入额外的依赖(毕竟除法并不难),但如果你使用的是 Commons Lang,那么有DurationFormatUtils。

示例用法(改编自here):

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 对象中获取毫秒,您可以使用:

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

【讨论】:

太好了,我只是在问自己是否有一个包含此类内容的强大库。 由于链接一般不是很有用,所以我添加了一个如何使用它的示例。【参考方案8】:

只是为了添加更多信息 如果你想像这样格式化:HH:mm:ss

0

0

0

使用这个:

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

我现在刚刚遇到这个问题并想通了

【讨论】:

最佳答案在这里。为什么每个人都想把事情弄得这么复杂?伙计们,这是简单的数学运算。【参考方案9】:

最短的解决方案:

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

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

例如哪些输出:

00:18:32

说明:

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

%tT 也接受 long 作为输入,因此无需创建 Dateprintf() 将简单地打印以毫秒为单位的时间,但在当前时区中,因此我们必须减去当前时区的原始偏移量,这样 0 毫秒将是 0 小时,而不是当前时区的时间偏移值.

注意#1:如果你需要String的结果,你可以这样得到:

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

注意 #2:这仅在 millis 小于一天时给出正确的结果,因为输出中不包含天部分。

【讨论】:

这是一个非常好的捷径,但是当我使用它时,我没有得到预期的结果。所以我有:long millis = 8398;,当我将它传递给String.format("%tT", millis) 时,我的输出是 19:00:08。 19 来自哪里? @Nelda.techspiress 那是您的时区的偏移量。您必须从中减去TimeZone.getDefault().getRawOffset(),正如答案中所写:String.format("%tT", millis-TimeZone.getDefault().getRawOffset()) 处理好了。谢谢你的澄清。【参考方案10】:

我认为最好的方法是:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toSeconds(length)/60,
    TimeUnit.MILLISECONDS.toSeconds(length) % 60 );

【讨论】:

你可以使用 TimeUnit.MILLISECONDS.toMinutes(length) 分钟【参考方案11】:

乔达时间

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

【讨论】:

不需要最后一行的PeriodFormat。只需调用Period::toString 即可默认获取ISO 8601 Duration 字符串。【参考方案12】:

重温@brent-nash 的贡献,我们可以使用模函数而不是减法,并使用 String.format 方法处理结果字符串:

  /**
   * 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);
   

【讨论】:

【参考方案13】:

适用于 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)) 

【讨论】:

【参考方案14】:

对于那些正在寻找 Kotlin 代码的人:

fun converter(millis: Long): String =
        String.format(
            "%02d : %02d : %02d",
            TimeUnit.MILLISECONDS.toHours(millis),
            TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(
                TimeUnit.MILLISECONDS.toHours(millis)
            ),
            TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(
                TimeUnit.MILLISECONDS.toMinutes(millis)
            )
        )

示例输出:09 : 10 : 26

【讨论】:

【参考方案15】:

我的简单计算:

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

编码愉快:)

【讨论】:

我认为 long 更适合这个函数,因为 System.currentTimeMillis() 返回一个 long 值。【参考方案16】:

首先,System.currentTimeMillis()Instant.now() 不适合计时。它们都报告挂钟时间,计算机无法准确知道该时间,并且可能会不规律地移动,包括向后,如果例如 NTP 守护程序更正系统时间。如果你的时间发生在单台机器上,那么你应该改用System.nanoTime()。

其次,从 Java 8 开始,java.time.Duration 是表示持续时间的最佳方式:

long start = System.nanoTime();
// do things...
long end = System.nanoTime();
Duration duration = Duration.ofNanos(end - start);
System.out.println(duration); // Prints "PT18M19.511627776S"
System.out.printf("%d Hours %d Minutes %d Seconds%n",
        duration.toHours(), duration.toMinutes() % 60, duration.getSeconds() % 60);
// prints "0 Hours 18 Minutes 19 Seconds"

【讨论】:

这是第一个结果之一,当您结合“android”搜索它时。【参考方案17】:

对于小时候,不到一个小时,我更喜欢:

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

【讨论】:

这是一个宝贵的提示,Java Formatter API (docs.oracle.com/javase/8/docs/api/java/util/Formatter.html) 有很多这样的日期和时间可能性!你也可以得到 else 条件结果: System.out.printf("%1$tH:%1$tM:%1$tS%n", millis);甚至 System.out.printf("%1$tT%n", millis); @JoseTepedino 但您知道%tH 显示从 0 到 23 小时?这意味着例如 24 小时将显示为00,25 小时将显示为01...同样适用于%tT - 天数将被默默地丢弃。当然,也可以显示日期,但这对于我写这篇文章时遇到的问题(早在 2011 年)[:-) 我明白了……这真的只能在不到一天(24 小时)的时间内工作。谢谢。【参考方案18】:

这是基于 Brent Nash 答案的答案,希望对您有所帮助!

public static String getDurationBreakdown(long millis)

    String[] units = " Days ", " Hours ", " Minutes ", " Seconds ";
    Long[] values = new Long[units.length];
    if(millis < 0)
    
        throw new IllegalArgumentException("Duration must be greater than zero!");
    

    values[0] = TimeUnit.MILLISECONDS.toDays(millis);
    millis -= TimeUnit.DAYS.toMillis(values[0]);
    values[1] = TimeUnit.MILLISECONDS.toHours(millis);
    millis -= TimeUnit.HOURS.toMillis(values[1]);
    values[2] = TimeUnit.MILLISECONDS.toMinutes(millis);
    millis -= TimeUnit.MINUTES.toMillis(values[2]);
    values[3] = TimeUnit.MILLISECONDS.toSeconds(millis);

    StringBuilder sb = new StringBuilder(64);
    boolean startPrinting = false;
    for(int i = 0; i < units.length; i++)
        if( !startPrinting && values[i] != 0)
            startPrinting = true;
        if(startPrinting)
            sb.append(values[i]);
            sb.append(units[i]);
        
    

    return(sb.toString());

【讨论】:

【参考方案19】:
    long startTime = System.currentTimeMillis();
    // do your work...
    long endTime=System.currentTimeMillis();
    long diff=endTime-startTime;       
    long hours=TimeUnit.MILLISECONDS.toHours(diff);
    diff=diff-(hours*60*60*1000);
    long min=TimeUnit.MILLISECONDS.toMinutes(diff);
    diff=diff-(min*60*1000);
    long seconds=TimeUnit.MILLISECONDS.toSeconds(diff);
    //hour, min and seconds variables contains the time elapsed on your work

【讨论】:

第6行的公式是错误的。 diff=diff-(hours*60*1000); 应该是 diff=diff-(hours*60*60*1000);。我尝试编辑它,但 *** 烦人的编辑政策说它没有足够的字符进行编辑。【参考方案20】:

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

    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

【讨论】:

【参考方案21】:

这个答案类似于上面的一些答案。但是,我认为这将是有益的,因为与其他答案不同,这将删除任何额外的逗号或空格并处理缩写。

/**
 * 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);

【讨论】:

【参考方案22】:

有问题。当毫秒为 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);

【讨论】:

【参考方案23】:

对于正确的字符串(“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";

【讨论】:

【参考方案24】:

我已经在另一个 answer 中介绍过这个,但你可以这样做:

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,单位已排序。

由您决定如何根据目标区域设置国际化这些数据。

【讨论】:

【参考方案25】:

这在 Java 9 中更容易:

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

这会产生一个类似0 hours, 39 mins, 9 seconds 的字符串。

如果您想在格式化前四舍五入到整秒:

    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 mins, 9 seconds

要打印带前导零的分钟和秒以使它们始终为两位数,只需将02 插入相关的格式说明符中,因此:

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

现在我们可以拥有例如0 hours, 39 mins, 09 seconds

【讨论】:

当前面的数字为 0 时,是否有任何格式可以删除小时/分钟/秒?我的意思是在 if else 条件下是可以实现的,但是如果存在这种字符串格式或类似的东西呢,有吗? 不,抱歉,@FARID,你需要if-else【参考方案26】:

DurationFormatUtils.formatDurationHMS(long)

【讨论】:

【参考方案27】:

我修改了@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【参考方案28】:

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

【讨论】:

以上是关于如何在 Java 中将毫秒转换为“X 分钟,x 秒”?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中将毫秒转换为日期格式?

如何在 Django 中将日期时间转换为毫秒?

如何在 Redshift 中将时间戳(具有毫秒)转换为 EPOCH

如何在 C++ 中将毫秒时间转换为 FILETIME

如何在 AngularJS 中将毫秒转换为分钟

如何在 Oracle 中将毫秒转换为 hh mm ss 格式