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

Cli*_*ote 548 java time

我想记录System.currentTimeMillis()用户在我的程序中开始使用时的时间.当他完成后,我会减去当前System.currentTimeMillis()start变量,我想向他们展示使用人类可读的格式经过诸如"XX小时XX分钟,XX秒",甚至是"XX分钟,XX秒",因为它的时间一个小时不太可能带人

最好的方法是什么?

sid*_*dev 1177

使用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))
);
Run Code Online (Sandbox Code Playgroud)

注意: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))
);
Run Code Online (Sandbox Code Playgroud)

如果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...
Run Code Online (Sandbox Code Playgroud)

  • 我建议使用mod 60而不是减去分钟,它看起来更干净.但是,需要知道1分钟= 60秒才能做到这一点... =) (6认同)
  • int months =(int)((float)days/30.4368499f); int years =(int)((float)days/365.242199f); (5认同)
  • `int hours =(int)((毫秒/(1000*60*60))%24)`这不起作用!相反,它应该像这样`int hours =(int)(毫秒/(1000*60*60));` (5认同)
  • 如果有人想要一个视频文件格式(**h:mm:ss**):`String.format("%01d:%02d:%02d",小时,分钟,秒); (4认同)
  • @AndreasDietrich SimpleDateFormat不适用于时差,因为它只从纪元返回日期! (2认同)
  • 有一个问题。当毫秒为 59999 时,实际上是 1 分钟,但会计算为 59 秒,丢失 999 毫秒。 (2认同)

Bre*_*ode 121

根据@ 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());
    }
Run Code Online (Sandbox Code Playgroud)

  • 我们可以使用模数函数而不是减法:`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分钟%d秒%d毫秒",天,小时,分钟,秒,毫秒);` (5认同)
  • 为了避免这种情况,您应该在此处进行单/多检查:`1天1小时1分1秒' (2认同)

小智 72

long time = 1536259;

return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));
Run Code Online (Sandbox Code Playgroud)

打印:

25:36:259

  • 时区不是这里唯一的问题......这个答案具有误导性,可能会严重混淆 Java 新手。即使忽略多余的外括号,OP 也询问如何呈现 _duration_(两个时间点之间的差异,以毫秒为单位)。将该持续时间称为“时间”并将其视为自 1970 年 1 月 1 日以来的偏移量只是为了格式化其较小的组件只是......错误的imo。更重要的是,3 年前 [this answer](http://stackoverflow.com/a/625444/983430) 已经提出了完全相同的方法(有关时区问题的更多详细信息,请参阅那里的评论)。 (3认同)
  • 这里有点晚了:)但你不需要把simpleDateFormat.setTimezone(TimeZone.getTimeZone("GMT"))放在这里,除非那是你的实际时区吗? (2认同)

Bom*_*mbe 34

嗯...一秒钟多少毫秒?一会儿?分工不是那么难.

int seconds = (int) ((milliseconds / 1000) % 60);
int minutes = (int) ((milliseconds / 1000) / 60);
Run Code Online (Sandbox Code Playgroud)

像这样继续几小时,几天,几周,几个月,一年,几十年,等等.

  • System.currentTimeMillis()不受DST的影响,因此不会因额外或缺少的小时而混淆.如果需要显示两个特定日期之间的差异,最好使用给定时间构造Date对象,并显示这两者之间的差异. (5认同)
  • 实际上,这样做超过一个小时都不是一个好主意,因为当涉及夏时制(23天或24小时)或leap年时,结果可能是错误的/不直观的。如果我阅读“ X将在1年/月发生”,我希望它是相同的日期和时间。 (2认同)

Vit*_*nko 30

在Java 8中使用java.time包:

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));
Run Code Online (Sandbox Code Playgroud)

输出为ISO 8601持续时间格式 :( PT1M3.553S1分钟和3.553秒).

  • 另请参阅 [如何在 Java 中格式化持续时间?(例如格式 H:MM:SS)](/sf/ask/18677781/​​mmss) (2认同)
  • (ANDROID) 需要 API 级别 26 (2认同)
  • @SomeoneSomewhere 对于 API 级别 26 下的 Android 使用向后移植,请参阅[如何在 Android 项目中使用 ThreeTenABP](/sf/ask/2724592811/)。 (2认同)

Thi*_*ilo 27

我不会仅仅为了那个拉出额外的依赖(毕竟分裂并不那么难),但是如果你还在使用Commons Lang,那么就有了DurationFormatUtils.


cad*_*ian 25

手动分区,或使用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)));
Run Code Online (Sandbox Code Playgroud)

Bombe编辑:评论中显示,这种方法仅适用于较小的持续时间(即不到一天).

  • 干部,现在它只能工作不到一天.小时数始终在0到23之间(包括0和23). (2认同)

fre*_*crs 21

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

0 <= HH <=无限

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);
Run Code Online (Sandbox Code Playgroud)

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


小智 12

我认为最好的方法是:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toSeconds(length)/60,
    TimeUnit.MILLISECONDS.toSeconds(length) % 60 );
Run Code Online (Sandbox Code Playgroud)


icz*_*cza 11

最短的解决方案:

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

System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());
Run Code Online (Sandbox Code Playgroud)

以哪些输出为例:

00:18:32
Run Code Online (Sandbox Code Playgroud)

说明:

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

%tT也接受long作为输入,所以不需要创建Date.printf()将只打印以毫秒为单位指定的时间,但在当前时区中,我们必须减去当前时区的原始偏移量,使0毫秒为0小时,而不是当前时区的时间偏移值.

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

String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());
Run Code Online (Sandbox Code Playgroud)

注意#2:如果millis小于一天,这只会给出正确的结果,因为输出中不包含日期部分.


Kaa*_*edi 9

对于那些寻找 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)
            )
        )
Run Code Online (Sandbox Code Playgroud)

示例输出:09 : 10 : 26


dog*_*ane 7

乔达时间

使用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));
Run Code Online (Sandbox Code Playgroud)


Jos*_*ino 7

重新访问@ 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);
   }
Run Code Online (Sandbox Code Playgroud)


Pra*_*eep 5

适用于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)) 
Run Code Online (Sandbox Code Playgroud)


Sho*_*jan 5

我的简单计算:

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);
}
Run Code Online (Sandbox Code Playgroud)

快乐的编码:)


Mik*_*Hay 5

首先,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"
Run Code Online (Sandbox Code Playgroud)