【问题标题】:How to convert milliseconds into human readable form?如何将毫秒转换为人类可读的形式?
【发布时间】:2010-09-15 14:08:53
【问题描述】:

我需要将任意数量的毫秒转换为天、小时、分秒。

例如:10 天,5 小时,13 分钟,1 秒。

【问题讨论】:

  • "我使用的语言没有内置这个,否则我会使用它。"我觉得这很难理解。什么语言?什么操作系统?
  • ActionScript,任何操作系统,它都支持糟糕的日期/时间
  • 我不知道有什么语言可以满足他的要求,我也看不出有任何理由。一些非常简单的除法/模数数学得到了很好的答案。
  • 并非所有年份的天数都相同,因此您必须说明是哪个时期。或者,您只是想要在“标准”年份(365.something)?
  • @Kip:知道了——误读了问题——以毫秒为单位考虑操作系统时间戳。不是增量时间或间隔。想编辑问题...

标签: date time string-formatting datetime-format


【解决方案1】:

这个省略了 0 个值。有测试。

const toTimeString = (value, singularName) =>
  `${value} ${singularName}${value !== 1 ? 's' : ''}`;

const readableTime = (ms) => {
  const days = Math.floor(ms / (24 * 60 * 60 * 1000));
  const daysMs = ms % (24 * 60 * 60 * 1000);
  const hours = Math.floor(daysMs / (60 * 60 * 1000));
  const hoursMs = ms % (60 * 60 * 1000);
  const minutes = Math.floor(hoursMs / (60 * 1000));
  const minutesMs = ms % (60 * 1000);
  const seconds = Math.round(minutesMs / 1000);

  const data = [
    [days, 'day'],
    [hours, 'hour'],
    [minutes, 'minute'],
    [seconds, 'second'],
  ];

  return data
    .filter(([value]) => value > 0)
    .map(([value, name]) => toTimeString(value, name))
    .join(', ');
};

// Tests
const hundredDaysTwentyHoursFiftyMinutesThirtySeconds = 8715030000;
const oneDayTwoHoursEightMinutesTwelveSeconds = 94092000;
const twoHoursFiftyMinutes = 10200000;
const oneMinute = 60000;
const fortySeconds = 40000;
const oneSecond = 1000;
const oneDayTwelveSeconds = 86412000;

const test = (result, expected) => {
  console.log(expected, '- ' + (result === expected));
};

test(readableTime(
  hundredDaysTwentyHoursFiftyMinutesThirtySeconds
), '100 days, 20 hours, 50 minutes, 30 seconds');

test(readableTime(
  oneDayTwoHoursEightMinutesTwelveSeconds
), '1 day, 2 hours, 8 minutes, 12 seconds');

test(readableTime(
  twoHoursFiftyMinutes
), '2 hours, 50 minutes');

test(readableTime(
  oneMinute
), '1 minute');

test(readableTime(
  fortySeconds
), '40 seconds');

test(readableTime(
  oneSecond
), '1 second');

test(readableTime(
  oneDayTwelveSeconds
), '1 day, 12 seconds');

【讨论】:

    【解决方案2】:

    在 python 3 中,您可以使用以下 sn-p 来实现您的目标:

    from datetime import timedelta
    
    ms = 536643021
    td = timedelta(milliseconds=ms)
    
    print(str(td))
    # --> 6 days, 5:04:03.021000
    

    时间增量文档:https://docs.python.org/3/library/datetime.html#datetime.timedelta

    timedelta str的__str__方法来源:https://github.com/python/cpython/blob/33922cb0aa0c81ebff91ab4e938a58dfec2acf19/Lib/datetime.py#L607

    【讨论】:

      【解决方案3】:

      使用awk的解决方案:

      $ ms=10000001; awk -v ms=$ms 'BEGIN {x=ms/1000; 
                                           s=x%60; x/=60;
                                           m=x%60; x/=60;
                                           h=x%60;
                                    printf("%02d:%02d:%02d.%03d\n", h, m, s, ms%1000)}'
      02:46:40.001
      

      【讨论】:

        【解决方案4】:

        在java中

        public static String formatMs(long millis) {
            long hours = TimeUnit.MILLISECONDS.toHours(millis);
            long mins = TimeUnit.MILLISECONDS.toMinutes(millis);
            long secs = TimeUnit.MILLISECONDS.toSeconds(millis);
            return String.format("%dh %d min, %d sec",
                    hours,
                    mins - TimeUnit.HOURS.toMinutes(hours),
                    secs - TimeUnit.MINUTES.toSeconds(mins)
            );
        }
        

        给出这样的东西:

        12h 1 min, 34 sec
        

        【讨论】:

          【解决方案5】:

          以下两种解决方案都使用 javascript(我不知道该解决方案与语言无关!)。如果捕获持续时间> 1 month,则需要扩展这两种解决方案。

          解决方案 1:使用 Date 对象

          var date = new Date(536643021);
          var str = '';
          str += date.getUTCDate()-1 + " days, ";
          str += date.getUTCHours() + " hours, ";
          str += date.getUTCMinutes() + " minutes, ";
          str += date.getUTCSeconds() + " seconds, ";
          str += date.getUTCMilliseconds() + " millis";
          console.log(str);
          

          给予:

          "6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
          

          库很有帮助,但既然可以重新发明轮子,为什么还要使用库! :)

          解决方案 2:编写自己的解析器

          var getDuration = function(millis){
              var dur = {};
              var units = [
                  {label:"millis",    mod:1000},
                  {label:"seconds",   mod:60},
                  {label:"minutes",   mod:60},
                  {label:"hours",     mod:24},
                  {label:"days",      mod:31}
              ];
              // calculate the individual unit values...
              units.forEach(function(u){
                  millis = (millis - (dur[u.label] = (millis % u.mod))) / u.mod;
              });
              // convert object to a string representation...
              var nonZero = function(u){ return dur[u.label]; };
              dur.toString = function(){
                  return units
                      .reverse()
                      .filter(nonZero)
                      .map(function(u){
                          return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label);
                      })
                      .join(', ');
              };
              return dur;
          };
          

          创建一个“持续时间”对象,包含您需要的任何字段。 格式化时间戳然后变得简单......

          console.log(getDuration(536643021).toString());
          

          给予:

          "6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
          

          【讨论】:

          • 更改该行以获得单数和复数return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label);
          • @PhillipKamikaze 谢谢菲利普!我采纳了你的建议。
          • 您可能不想显示零值的段,因此可以添加以下过滤器...var nonZero = function(u){ return !u.startsWith("0"); }; // convert object to a string representation... dur.toString = function(){ return units.reverse().map(function(u){ return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label); }).filter(nonZero).join(', '); };
          • 谢谢@RuslanUlanov!我已将其添加到示例中(尽管稍作修改以检查数字是否“真实”)。
          【解决方案6】:

          这里是JAVA中更精确的方法,我实现了这个简单的逻辑,希望对你有帮助:

              public String getDuration(String _currentTimemilliSecond)
              {
                  long _currentTimeMiles = 1;         
                  int x = 0;
                  int seconds = 0;
                  int minutes = 0;
                  int hours = 0;
                  int days = 0;
                  int month = 0;
                  int year = 0;
          
                  try 
                  {
                      _currentTimeMiles = Long.parseLong(_currentTimemilliSecond);
                      /**  x in seconds **/   
                      x = (int) (_currentTimeMiles / 1000) ; 
                      seconds = x ;
          
                      if(seconds >59)
                      {
                          minutes = seconds/60 ;
          
                          if(minutes > 59)
                          {
                              hours = minutes/60;
          
                              if(hours > 23)
                              {
                                  days = hours/24 ;
          
                                  if(days > 30)
                                  {
                                      month = days/30;
          
                                      if(month > 11)
                                      {
                                          year = month/12;
          
                                          Log.d("Year", year);
                                          Log.d("Month", month%12);
                                          Log.d("Days", days % 30);
                                          Log.d("hours ", hours % 24);
                                          Log.d("Minutes ", minutes % 60);
                                          Log.d("Seconds  ", seconds % 60);   
          
                                          return "Year "+year + " Month "+month%12 +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                                      }
                                      else
                                      {
                                          Log.d("Month", month);
                                          Log.d("Days", days % 30);
                                          Log.d("hours ", hours % 24);
                                          Log.d("Minutes ", minutes % 60);
                                          Log.d("Seconds  ", seconds % 60);   
          
                                          return "Month "+month +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                                      }
          
                                  }
                                  else
                                  {
                                      Log.d("Days", days );
                                      Log.d("hours ", hours % 24);
                                      Log.d("Minutes ", minutes % 60);
                                      Log.d("Seconds  ", seconds % 60);   
          
                                      return "Days " +days +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                                  }
          
                              }
                              else
                              {
                                  Log.d("hours ", hours);
                                  Log.d("Minutes ", minutes % 60);
                                  Log.d("Seconds  ", seconds % 60);
          
                                  return "hours "+hours+" Minutes "+minutes %60+" Seconds "+seconds%60;
                              }
                          }
                          else
                          {
                              Log.d("Minutes ", minutes);
                              Log.d("Seconds  ", seconds % 60);
          
                              return "Minutes "+minutes +" Seconds "+seconds%60;
                          }
                      }
                      else
                      {
                          Log.d("Seconds ", x);
                          return " Seconds "+seconds;
                      }
                  }
                  catch (Exception e) 
                  {
                      Log.e(getClass().getName().toString(), e.toString());
                  }
                  return "";
              }
          
              private Class Log
              {
                  public static void d(String tag , int value)
                  {
                      System.out.println("##### [ Debug ]  ## "+tag +" :: "+value);
                  }
              }
          

          【讨论】:

            【解决方案7】:

            我建议使用http://www.ocpsoft.org/prettytime/ library..

            以人类可读的形式获取时间间隔非常简单,例如

            PrettyTime p = new PrettyTime(); System.out.println(p.format(new Date()));

            它会像“从现在开始”一样打印出来

            其他例子

            PrettyTime p = new PrettyTime()); Date d = new Date(System.currentTimeMillis()); d.setHours(d.getHours() - 1); String ago = p.format(d);

            然后字符串 ago = "1 小时前"

            【讨论】:

              【解决方案8】:

              为什么不这样做:

              var ms = 86400;

              var 秒 = 毫秒 / 1000; //86.4

              var 分钟 = 秒 / 60; //1.4400000000000002

              var 小时 = 分钟 / 60; //0.024000000000000004

              var 天数 = 小时 / 24; //0.0010000000000000002

              并处理浮点精度,例如Number(minutes.toFixed(5)) //1.44

              【讨论】:

                【解决方案9】:

                一种灵活的方式:
                (不适用于当前日期,但足够持续时间)

                /**
                convert duration to a ms/sec/min/hour/day/week array
                @param {int}        msTime              : time in milliseconds 
                @param {bool}       fillEmpty(optional) : fill array values even when they are 0.
                @param {string[]}   suffixes(optional)  : add suffixes to returned values.
                                                        values are filled with missings '0'
                @return {int[]/string[]} : time values from higher to lower(ms) range.
                */
                var msToTimeList=function(msTime,fillEmpty,suffixes){
                    suffixes=(suffixes instanceof Array)?suffixes:[];   //suffixes is optional
                    var timeSteps=[1000,60,60,24,7];    // time ranges : ms/sec/min/hour/day/week
                    timeSteps.push(1000000);    //add very big time at the end to stop cutting
                    var result=[];
                    for(var i=0;(msTime>0||i<1||fillEmpty)&&i<timeSteps.length;i++){
                        var timerange = msTime%timeSteps[i];
                        if(typeof(suffixes[i])=="string"){
                            timerange+=suffixes[i]; // add suffix (converting )
                            // and fill zeros :
                            while(  i<timeSteps.length-1 &&
                                    timerange.length<((timeSteps[i]-1)+suffixes[i]).length  )
                                timerange="0"+timerange;
                        }
                        result.unshift(timerange);  // stack time range from higher to lower
                        msTime = Math.floor(msTime/timeSteps[i]);
                    }
                    return result;
                };
                

                注意:如果您想控制时间范围,也可以将 timeSteps 设置为参数。

                如何使用(复制一个测试):

                var elsapsed = Math.floor(Math.random()*3000000000);
                
                console.log(    "elsapsed (labels) = "+
                        msToTimeList(elsapsed,false,["ms","sec","min","h","days","weeks"]).join("/")    );
                
                console.log(    "half hour : "+msToTimeList(elsapsed,true)[3]<30?"first":"second"   );
                
                console.log(    "elsapsed (classic) = "+
                        msToTimeList(elsapsed,false,["","","","","",""]).join(" : ")    );
                

                【讨论】:

                  【解决方案10】:

                  这是我使用 TimeUnit 的解决方案。

                  更新:我应该指出这是用 groovy 编写的,但 Java 几乎相同。

                  def remainingStr = ""
                  
                  /* Days */
                  int days = MILLISECONDS.toDays(remainingTime) as int
                  remainingStr += (days == 1) ? '1 Day : ' : "${days} Days : "
                  remainingTime -= DAYS.toMillis(days)
                  
                  /* Hours */
                  int hours = MILLISECONDS.toHours(remainingTime) as int
                  remainingStr += (hours == 1) ? '1 Hour : ' : "${hours} Hours : "
                  remainingTime -= HOURS.toMillis(hours)
                  
                  /* Minutes */
                  int minutes = MILLISECONDS.toMinutes(remainingTime) as int
                  remainingStr += (minutes == 1) ? '1 Minute : ' : "${minutes} Minutes : "
                  remainingTime -= MINUTES.toMillis(minutes)
                  
                  /* Seconds */
                  int seconds = MILLISECONDS.toSeconds(remainingTime) as int
                  remainingStr += (seconds == 1) ? '1 Second' : "${seconds} Seconds"
                  

                  【讨论】:

                    【解决方案11】:

                    Apache Commons Lang 有一个 DurationFormatUtils 有非常有用的方法,例如 formatDurationWords

                    【讨论】:

                    • 谢谢!当它出现在我已经拥有的图书馆时,我很喜欢它......
                    • 这是专业的答案!
                    【解决方案12】:
                    Long expireTime = 69l;
                    Long tempParam = 0l;
                    
                    Long seconds = math.mod(expireTime, 60);
                    tempParam = expireTime - seconds;
                    expireTime = tempParam/60;
                    Long minutes = math.mod(expireTime, 60);
                    tempParam = expireTime - minutes;
                    expireTime = expireTime/60;
                    Long hours = math.mod(expireTime, 24);
                    tempParam = expireTime - hours;
                    expireTime = expireTime/24;
                    Long days = math.mod(expireTime, 30);
                    
                    system.debug(days + '.' + hours + ':' + minutes + ':' + seconds);
                    

                    这应该打印:0.0:1:9

                    【讨论】:

                      【解决方案13】:

                      这是一个解决方案。稍后您可以通过“:”拆分并获取数组的值

                      /**
                       * Converts milliseconds to human readeable language separated by ":"
                       * Example: 190980000 --> 2:05:3 --> 2days 5hours 3min
                       */
                      function dhm(t){
                          var cd = 24 * 60 * 60 * 1000,
                              ch = 60 * 60 * 1000,
                              d = Math.floor(t / cd),
                              h = '0' + Math.floor( (t - d * cd) / ch),
                              m = '0' + Math.round( (t - d * cd - h * ch) / 60000);
                          return [d, h.substr(-2), m.substr(-2)].join(':');
                      }
                      
                      var delay = 190980000;                   
                      var fullTime = dhm(delay);
                      console.log(fullTime);
                      

                      【讨论】:

                        【解决方案14】:

                        好吧,既然没有其他人站出来,我将编写简单的代码来做到这一点:

                        x = ms / 1000
                        seconds = x % 60
                        x /= 60
                        minutes = x % 60
                        x /= 60
                        hours = x % 24
                        x /= 24
                        days = x
                        

                        我很高兴你几天都停下来,几个月都没有要求。 :)

                        注意,在上面,假设/代表截断整数除法。如果您在/ 表示浮点除法的语言中使用此代码,则需要根据需要手动截断除法的结果。

                        【讨论】:

                        • 刚刚在flash函数中使用了那个。谢谢! (为简单起见投票)
                        • 它不能正常工作。使用除数时应使用 parseInt,否则您将看到长浮点值。请参阅下面的答案以获得更全面的解决方案。
                        • @Greg Hewgill 我很高兴你几天都停下来,几个月都没有问。 :) 哈哈 :)
                        【解决方案15】:

                        我无法评论您的问题的第一个答案,但有一个小错误。您应该使用 parseInt 或 Math.floor 将浮点数转换为整数,i

                        var days, hours, minutes, seconds, x;
                        x = ms / 1000;
                        seconds = Math.floor(x % 60);
                        x /= 60;
                        minutes = Math.floor(x % 60);
                        x /= 60;
                        hours = Math.floor(x % 24);
                        x /= 24;
                        days = Math.floor(x);
                        

                        就我个人而言,我在我的项目中使用 CoffeeScript,我的代码如下所示:

                        getFormattedTime : (ms)->
                                x = ms / 1000
                                seconds = Math.floor x % 60
                                x /= 60
                                minutes = Math.floor x % 60
                                x /= 60
                                hours = Math.floor x % 24
                                x /= 24
                                days = Math.floor x
                                formattedTime = "#{seconds}s"
                                if minutes then formattedTime = "#{minutes}m " + formattedTime
                                if hours then formattedTime = "#{hours}h " + formattedTime
                                formattedTime 
                        

                        【讨论】:

                          【解决方案16】:
                          function convertTime(time) {        
                              var millis= time % 1000;
                              time = parseInt(time/1000);
                              var seconds = time % 60;
                              time = parseInt(time/60);
                              var minutes = time % 60;
                              time = parseInt(time/60);
                              var hours = time % 24;
                              var out = "";
                              if(hours && hours > 0) out += hours + " " + ((hours == 1)?"hr":"hrs") + " ";
                              if(minutes && minutes > 0) out += minutes + " " + ((minutes == 1)?"min":"mins") + " ";
                              if(seconds && seconds > 0) out += seconds + " " + ((seconds == 1)?"sec":"secs") + " ";
                              if(millis&& millis> 0) out += millis+ " " + ((millis== 1)?"msec":"msecs") + " ";
                              return out.trim();
                          }
                          

                          【讨论】:

                            【解决方案17】:

                            这是我写的一个方法。它接受integer milliseconds value 并返回human-readable String

                            public String convertMS(int ms) {
                                int seconds = (int) ((ms / 1000) % 60);
                                int minutes = (int) (((ms / 1000) / 60) % 60);
                                int hours = (int) ((((ms / 1000) / 60) / 60) % 24);
                            
                                String sec, min, hrs;
                                if(seconds<10)  sec="0"+seconds;
                                else            sec= ""+seconds;
                                if(minutes<10)  min="0"+minutes;
                                else            min= ""+minutes;
                                if(hours<10)    hrs="0"+hours;
                                else            hrs= ""+hours;
                            
                                if(hours == 0)  return min+":"+sec;
                                else    return hrs+":"+min+":"+sec;
                            
                            }
                            

                            【讨论】:

                              【解决方案18】:
                              Long serverUptimeSeconds = 
                                  (System.currentTimeMillis() - SINCE_TIME_IN_MILLISECONDS) / 1000;
                              
                              
                              String serverUptimeText = 
                              String.format("%d days %d hours %d minutes %d seconds",
                              serverUptimeSeconds / 86400,
                              ( serverUptimeSeconds % 86400) / 3600 ,
                              ((serverUptimeSeconds % 86400) % 3600 ) / 60,
                              ((serverUptimeSeconds % 86400) % 3600 ) % 60
                              );
                              

                              【讨论】:

                                【解决方案19】:

                                令 A 为毫秒数。那么你有:

                                seconds=(A/1000)%60
                                minutes=(A/(1000*60))%60
                                hours=(A/(1000*60*60))%24
                                

                                以此类推(% 是取模运算符)。

                                希望这会有所帮助。

                                【讨论】:

                                • @sabbibJAVA 24 应该可以工作。你用什么语言?如果/ 进行浮点除法,则需要截断该值。在其他答案中假设/ 正在执行整数除法。
                                【解决方案20】:

                                你应该使用你所使用的任何语言的日期时间函数,但是,这里的代码只是为了好玩:

                                int milliseconds = someNumber;
                                
                                int seconds = milliseconds / 1000;
                                
                                int minutes = seconds / 60;
                                
                                seconds %= 60;
                                
                                int hours = minutes / 60;
                                
                                minutes %= 60;
                                
                                int days = hours / 24;
                                
                                hours %= 24;
                                

                                【讨论】:

                                  【解决方案21】:

                                  您的选择很简单:

                                  1. 编写代码进行转换(即,除以milliSecondsPerDay 得到天数,使用模数除以milliSecondsPerHour 得到小时数,使用模数除以milliSecondsPerMinute,再除以1000 得到秒数。milliSecondsPerMinute = 60000, milliSecondsPerHour = 60 * milliSecondsPerMinute,milliSecondsPerDay = 24 * milliSecondsPerHour。
                                  2. 使用某种操作例程。 UNIX 和 Windows 都具有可以从 Ticks 或 seconds 类型值中获取的结构。

                                  【讨论】:

                                    【解决方案22】:

                                    我建议使用您选择的语言/框架提供的任何日期/时间函数/库。还可以查看字符串格式化函数,因为它们通常提供简单的方法来传递日期/时间戳并输出人类可读的字符串格式。

                                    【讨论】:

                                      猜你喜欢
                                      • 1970-01-01
                                      • 2012-12-02
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2015-07-24
                                      • 1970-01-01
                                      • 2018-12-13
                                      • 1970-01-01
                                      • 1970-01-01
                                      相关资源
                                      最近更新 更多