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

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

最好的方法是什么?

【问题讨论】:

  • 如果他们需要一个多小时,你仍然可以打印类似的东西; 90 分 53 秒。

标签: java time


【解决方案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 秒)。

【讨论】:

【解决方案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);。我尝试编辑它,但 StackOverflow 烦人的编辑政策说它没有足够的字符进行编辑。
          【解决方案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】:
                    【解决方案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));
                    

                    【讨论】:

                      猜你喜欢
                      • 2018-11-16
                      • 2014-03-18
                      • 2022-12-31
                      • 1970-01-01
                      • 2023-03-17
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多