【问题标题】:How to use format() on a moment.js duration?如何在 moment.js 持续时间内使用 format()?
【发布时间】:2012-10-27 02:09:35
【问题描述】:

有什么方法可以在持续时间对象上使用moment.jsformat 方法吗?我在文档中的任何地方都找不到它,而且它也不是持续时间对象的属性。

我希望能够做类似的事情:

var diff = moment(end).unix() - moment(start).unix();
moment.duration(diff).format('hh:mm:ss')

另外,如果有任何其他库可以轻松容纳此类功能,我会对推荐感兴趣。

谢谢!

【问题讨论】:

  • moment.utc(duration.asMilliseconds()).format('hh:mm:ss'); - 持续时间是一个向量。通过将其尾部放在原点上,您可以使用日期格式来获取 hh:mm:ss。
  • moment.utc(moment.duration(23, 'seconds').asMilliseconds()).format('hh:mm:ss') => "12:00:23" 没有工作得很好
  • 啊,我发现了问题,HH:mm:ss 将在我之前的示例中给出00:00:23。所以只是小时部分的错误大小写

标签: javascript momentjs duration


【解决方案1】:
// set up
let start = moment("2018-05-16 12:00:00"); // some random moment in time (in ms)
let end = moment("2018-05-16 12:22:00"); // some random moment after start (in ms)
let diff = end.diff(start);

// execution
let f = moment.utc(diff).format("HH:mm:ss.SSS");
alert(f);

Have a look at the JSFiddle

【讨论】:

  • 好方法。尽管如果我也想显示日期,它也不起作用:DDD HH:mm:ss.SSS(其中DDD 是一年中的某天)在我想要0 时显示1。有什么快速解决办法吗?
  • 不容易。我做了这个 jsfiddle.net/fhdd8/14 ,这可能是你所做的,但我不认为 moment 有任何开箱即用的东西
  • 将 10 万亿毫秒显示为 mm:ss 没有任何意义
  • 这在 24 小时后不起作用(即,如果我想显示 117 小时)。否则很好的解决方案!
  • @Phil 如果您想显示天数,可以使用“D”或“DD”。
【解决方案2】:

将持续时间转换为毫秒,然后转换为时刻:

moment.utc(duration.as('milliseconds')).format('HH:mm:ss')

【讨论】:

  • 因此,如果您的持续时间超过 24 小时,这将不起作用.. 24 小时被重置为 0 小时
  • @S.Robijns 是一个有用的观察,但只是为了向其他人强调 - 这 是 .format('HH:mm:ss') 的预期行为。 See the docs
【解决方案3】:

我们正在考虑在 moment.js 中为持续时间添加某种格式。见https://github.com/timrwood/moment/issues/463

http://countdownjs.org/ 和 https://github.com/icambron/twix.js 等其他几个库可能会有所帮助

【讨论】:

  • 我也期待持续时间格式。现在看一下 countdownjs,但 twix 似乎只做“智能”格式化,没有太多自定义。
  • 虽然 twix 努力进行智能格式化,但它有很多格式化选项,包括所涉及的标记:github.com/icambron/twix.js/wiki/Formatting。免责声明:我是 twix 的作者。
  • Countdown.js 非常好,作者超好用(因为我的一些建议,他当天才发布2个版本)!
  • 我投了反对票,因为这个答案中链接的 github 问题只是一个永无止境的意见、愿望和咆哮,无处可去,4 年后问题仍然存在,没有任何用处
  • 为什么它不能与库中其他地方使用的其他 .format 相同?这是精神错乱。 5年了还没有完成?真的吗?!
【解决方案4】:

使用这个插件Moment Duration Format。

例子:

moment.duration(123, "minutes").format("h:mm");

【讨论】:

  • 该格式无法正常工作,持续时间方面很好,但如果我指定 hh:mm:mm 并且只有 10 秒,它会显示 10 而不是 00:00:10(即使打开 forcelength)如果它不是格式化......那么它应该被称为别的东西,格式应该是标准化的。
  • @ppumkin 我知道这是旧的,但如果你指定 { trim: false } 它将停止这种行为。
  • 这是我更喜欢使用的:假设你有持续时间,比如const duration = moment.duration(value, 'seconds');,而不是我可以使用格式化:moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
  • @EvgenyBobkin 如果您的持续时间超过一天,它将无法工作,但图书馆会处理它
【解决方案5】:

使用这行代码:

moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss")

【讨论】:

  • 如果持续时间 > of 86400''(即 24 小时),这将不起作用。
  • excel中也是一样,24小时翻转。如果您知道 24 小时限制,这是一个很好的解决方法。
  • 所以当我使用 .utc 时,时间是 waaaaayyyy 关闭。为什么?
【解决方案6】:
var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");

【讨论】:

  • 一般来说,如果答案包括对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。 (该帖子至少被一位用户标记,大概是因为他们认为应该删除没有解释的答案。)
  • 无法解释,这对我来说是什么。谢谢:)
  • 不需要解释。 Moment.js 文档可以展示这个解决方案是如何实现的。
  • 没用。像这个问题的大多数其他答案一样,返回持续时间的部分小时而不是总小时。例如。持续时间返回 12:00 moment.duration({days: 2, hours: 12})
  • moment.duration(diff).asMilliseconds() 过多。您可以只使用 diff,它已经在毫秒内。
【解决方案7】:

我的特定用例的最佳方案是:

var duration = moment.duration("09:30"),
    formatted = moment.utc(duration.asMilliseconds()).format("HH:mm");

这改进了 @Wilson 的回答,因为它不访问私有内部属性 _data。

【讨论】:

    【解决方案8】:

    您不需要 .format。像这样使用持续时间:

    const duration = moment.duration(83, 'seconds');
    console.log(duration.minutes() + ':' +duration.seconds());
    // output: 1:23
    

    我在这里找到了这个解决方案:https://github.com/moment/moment/issues/463

    编辑:

    还有秒、分和小时的填充:

    const withPadding = (duration) => {
        if (duration.asDays() > 0) {
            return 'at least one day';
        } else {
            return [
                ('0' + duration.hours()).slice(-2),
                ('0' + duration.minutes()).slice(-2),
                ('0' + duration.seconds()).slice(-2),
            ].join(':')
        }
    }
    
    withPadding(moment.duration(83, 'seconds'))
    // 00:01:23
    
    withPadding(moment.duration(6048000, 'seconds'))
    // at least one day
    

    【讨论】:

    • 如果 duration.seconds() 小于 10,这将不包括前导零...
    • 如果秒数超过一小时会怎样?那么你有超过 60 秒的时间可以吗?
    • 前导零有效,但duration = moment.duration(7200, 'seconds'); withPadding(duration); 会说“00:00”。
    • @shaedrich 我再次更新了我的答案以包括小时数;如果您需要几天、几周,也可以将它们添加到数组中
    • if (duration.asDays() > 0) { return 'at least one day'; - 我读对了吗?
    【解决方案9】:

    我用:

    var duration = moment.duration("09:30");
    var str = moment(duration._data).format("HH:mm");
    

    我在 var str 中得到“09:30”。

    【讨论】:

    • 太棒了!这只是工作......你到底是怎么想出这个的:)
    • 避免这种解决方案,_data 是一个内部属性,可能会在没有警告的情况下更改。
    • 不幸的是,它不会总是按预期工作:moment(moment.duration(1200000)._data).format('hh:mm:ss') 将返回 12:20 而不是 00:20
    • @AnnaR h 在 1-12 范围内,所以这是可以预料的。使用H 而不是docs - hour tokens
    • 这是错误的,不仅你忽略了DAYS,所以1day和1hour会显示为01:00。此外,您完全忽略了时区,这是一个更好的解决方案,但 也不是完整的 将是 moment.utc(...).format("HH:mm");
    【解决方案10】:

    我需要这样做以作为以这种格式显示小时数的要求。 一开始我试过这个。

    moment.utc(totalMilliseconds).format("HH:mm:ss")
    

    但是,超过 24 小时的任何时间都将重置为 0。 但分钟和秒是准确的。 所以我只用那部分来表示分钟和秒。

    var minutesSeconds = moment.utc(totalMilliseconds).format("mm:ss")
    

    现在我只需要总小时数。

    var hours = moment.duration(totalMilliseconds).asHours().toFixed()
    

    为了获得我们都想要的格式,我们只需将它们粘合在一起即可。

    var formatted = hours + ":" + minutesSeconds
    

    如果totalMilliseconds 是894600000,这将返回249:30:00。

    希望对您有所帮助。在 cmets 中留下任何问题。 ;)

    【讨论】:

    • 不会'toFixed()' 将数字四舍五入吗?例如:“76.35”将变为“77”,而您想要的是“76”,然后将小时和分钟附加到它上面。我使用了 var hours = Math.floor(moment.duration(totalMilliseconds).asHours())。代码中的其他所有内容都很酷。感谢您的回答。
    【解决方案11】:

    如果差异是一瞬间

    var diff = moment(20111031) - moment(20111010);
    var formated1 = moment(diff).format("hh:mm:ss");
    console.log("format 1: "+formated1);
    

    【讨论】:

    • 面对时区等,这似乎并不可靠。你在生产中使用它吗?
    • 这个问题没有提到时区。
    • 每个人都生活在一个时区。时刻(0)是否总是在每个时区注册为 12:00 AM?
    • 我只是询问您答案中的代码是否有效,因为我持怀疑态度。我用许多编程语言编写了很多与日期一起使用的代码。根据我的经验,您的代码似乎只能在某些时区工作——但我之所以这么问,是因为我可能不知道 Javascript 如何表示 Unix 时代附近的日期。
    • 第二行将创建一个从时间开始(1970)开始的时刻。这不行。
    【解决方案12】:

    如果您愿意使用不同的 javascript 库,numeral.js 可以将秒格式化如下(示例为 1000 秒):

    var string = numeral(1000).format('00:00');
    // '00:16:40'
    

    【讨论】:

    • 绝对是要走的路。正如预期的那样。
    【解决方案13】:

    如果必须显示所有小时数(超过 24 个)并且如果小时数之前不需要“0”,则可以使用一小行代码进行格式化:

    Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss')
    

    【讨论】:

    • 这是最好的 h:mm 答案,但我认为最好的显示只是 moment.duration(val,'seconds').humanize()。
    • 对于我的用例,用mm 和ss 显示所有小时是最好的方法,因为它很紧凑,看起来类似于逗号分隔的值,因此有利于视觉比较。
    【解决方案14】:

    基于ni-ko-o-kin's answer:

    meassurements = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"];
    withPadding = (duration) => {
        var step = null;
        return meassurements.map((m) => duration[m]()).filter((n,i,a) => {
            var nonEmpty = Boolean(n);
            if (nonEmpty || step || i >= a.length - 2) {
                step = true;
            }
            return step;
        }).map((n) => ('0' + n).slice(-2)).join(':')
    }
    
    duration1 = moment.duration(1, 'seconds');
    duration2 = moment.duration(7200, 'seconds');
    duration3 = moment.duration(604800, 'seconds');
    
    withPadding(duration1); // 00:01
    withPadding(duration2); // 02:00:00
    withPadding(duration3); // 01:07:00:00:00
    

    【讨论】:

    • 我不认为它的可读性很强。你想在这里解决什么问题?你的用例是什么?
    • 我再次更新了我的答案以处理超过一天。它适用于我的用例。
    • 问题在于,在大多数情况下,您的解决方案并不理想,因为它包含太多前导零。谁想要返回“00:00:00:00:01”?我的解决方案是“可扩展的”,并根据需要添加尽可能多的前导零。
    • 完美运行。非常简单的输出。如果没有天数,则显示天数等不会为零。
    【解决方案15】:

    在这些情况下我使用经典的格式化功能:

    var diff = moment(end).unix() - moment(start).unix();
    
    //use unix function instead of difference
    moment.unix(diff).format('hh:mm:ss')
    

    这是一个 hack,因为时间差异被视为标准时刻日期,早期纪元日期时间,但这与我们的目标无关,您不需要任何插件

    【讨论】:

      【解决方案16】:

      将持续时间格式化为字符串

      var duration = moment.duration(86400000); //value in milliseconds
      var hours = duration.hours();
      var minutes = duration.minutes();
      var seconds = duration.seconds();
      var milliseconds = duration.milliseconds();
      
      var date = moment().hours(hours).minutes(minutes).seconds(seconds).millisecond(milliseconds);
      if (is12hr){
          return date.format("hh:mm:ss a");
      }else{
          return date.format("HH:mm:ss");
      }
      

      【讨论】:

        【解决方案17】:

        如果您使用 Angular,请将其添加到您的过滤器中:

        .filter('durationFormat', function () {
            return function (value) {
                var days = Math.floor(value/86400000);
                value = value%86400000;
                var hours = Math.floor(value/3600000);
                value = value%3600000;
                var minutes = Math.floor(value/60000);
                value = value%60000;
                var seconds = Math.floor(value/1000);
                return (days? days + ' days ': '') + (hours? hours + ' hours ': '') + (minutes? minutes + ' minutes ': '') + (seconds? seconds + ' seconds ': '')
            }
        })
        

        使用示例

        <div> {{diff | durationFormat}} </div>
        

        【讨论】:

        • 确实很好。我一直在寻找这样的“漂亮格式”。谢谢!
        【解决方案18】:

        我的解决方案不涉及任何其他库,它适用于 diff > 24h

        var momentInSeconds = moment.duration(n,'seconds')
        console.log(("0" + Math.floor(momentInSeconds.asHours())).slice(-2) + ':' + ("0" + momentInSeconds.minutes()).slice(-2) + ':' + ("0" + momentInSeconds.seconds()).slice(-2))
        

        【讨论】:

          【解决方案19】:

          原生 javascript 怎么样?

          var formatTime = function(integer) {
              if(integer < 10) {
                  return "0" + integer; 
              } else {
                  return integer;
              }
          }
          
          function getDuration(ms) {
              var s1 = Math.floor(ms/1000);
              var s2 = s1%60;
              var m1 = Math.floor(s1/60);
              var m2 = m1%60;
              var h1 = Math.floor(m1/60);
              var string = formatTime(h1) +":" + formatTime(m2) + ":" + formatTime(s2);
              return string;
          }
          

          【讨论】:

            【解决方案20】:

            moment.duration(x).format() 已被弃用。 您可以使用moment.utc(4366589).format("HH:mm:ss") 来获得所需的响应。

            console.log(moment.utc(4366589).format("HH:mm:ss"))
            <script src="https://momentjs.com/downloads/moment.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

            【讨论】:

              【解决方案21】:

              如何正确使用 moment.js 持续时间? | 在代码中使用 moment.duration()

              首先你需要导入moment和moment-duration-format。

              import moment from 'moment';
              import 'moment-duration-format';
              

              然后,使用持续时间函数。让我们应用上面的例子:28800 = 8 am。

              moment.duration(28800, "seconds").format("h:mm a");
              

              ?好吧,你没有上述类型错误。 ?早上 8:00 得到正确的值吗?不……,您得到的值是 8:00 a。 Moment.js 格式无法正常工作。

              ?解决方法是将秒转换为毫秒,并使用UTC时间。

              moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')
              

              好的,我们现在是上午 8:00。如果你想要 8 am 而不是 8:00 am 作为整数时间,我们需要做 RegExp

              const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
              time.replace(/:00/g, '')
              

              【讨论】:

                【解决方案22】:

                短版(单行):

                moment.duration(durationInMs).asHours()|0||"00" + ":" + moment.utc(durationInMs).format("mm:ss")
                

                加长版:

                export const formatDuration = (durationInMs) => {
                    const hours = Math.floor(moment.duration(durationInMs).asHours()) || "00"
                    return hours + ":" + moment.utc(durationInMs).format("mm:ss")
                }
                

                例子:

                【讨论】:

                  【解决方案23】:

                  使用moment-duration-format。

                  客户端框架(例如:React)

                  import moment from 'moment';
                  import momentDurationFormatSetup from 'moment-duration-format';
                  momentDurationFormatSetup(moment);
                  
                  const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
                  

                  服务器(node.js)

                  const moment = require("moment-timezone");
                  const momentDurationFormatSetup = require("moment-duration-format");
                  
                  momentDurationFormatSetup(moment);
                  
                  const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
                  

                  【讨论】:

                    【解决方案24】:

                    不再需要(如果有的话)将持续时间转换为 UTC 来解决此问题。这就像将 base10 的“1”转换为二进制,然后说由于输出“1”看起来像 base10,我们假设这是一个 base10 值,可以进行任何进一步的操作。

                    使用moment-duration-format 并注意使用{ trim: false } 可以防止修剪:

                    moment.duration(1000000, "seconds").format("hh:mm:ss", { trim: false })
                    > "277:46:40"
                    moment.duration(0, "seconds").format("hh:mm:ss", { trim: false })
                    > "00:00:00"
                    

                    我们把这个和不推荐的using滥用utc的方法对比一下:

                    moment.utc(moment.duration(1000000, "seconds").asMilliseconds()).format('HH:mm:ss')
                    > "13:46:40"
                    

                    【讨论】:

                      【解决方案25】:
                      const duration = moment.duration(62, 'hours');
                      const n = 24 * 60 * 60 * 1000;
                      const days = Math.floor(duration / n);
                      const str = moment.utc(duration % n).format('H [h] mm [min] ss [s]');
                      console.log(`${days > 0 ? `${days} ${days == 1 ? 'day' : 'days'} ` : ''}${str}`);
                      

                      打印:

                      2 天 14 小时 00 分 00 秒

                      【讨论】:

                        【解决方案26】:
                        import * as moment from 'moment'
                        var sleep = require('sleep-promise');
                        
                        (async function () {
                            var t1 = new Date().getTime();
                            await sleep(1000); 
                            var t2 = new Date().getTime();
                            var dur = moment.duration(t2-t1); 
                            console.log(`${dur.hours()}h:${dur.minutes()}m:${dur.seconds()}s`);
                        })();
                        
                        
                        0h:0m:1s
                        

                        【讨论】:

                          【解决方案27】:

                          您可以使用numeral.js 来格式化您的时长:

                          numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss
                          

                          【讨论】:

                            【解决方案28】:

                            这可用于将前两个字符作为小时,将后两个字符作为分钟。同样的逻辑也可以应用于秒。

                            /**
                                 * PT1H30M -> 0130
                                 * @param {ISO String} isoString
                                 * @return {string} absolute 4 digit number HH:mm
                                 */
                            
                                const parseIsoToAbsolute = (isoString) => {
                                
                                  const durations = moment.duration(isoString).as('seconds');
                                  const momentInSeconds = moment.duration(durations, 'seconds');
                                
                                  let hours = momentInSeconds.asHours().toString().length < 2
                                    ? momentInSeconds.asHours().toString().padStart(2, '0') : momentInSeconds.asHours().toString();
                                    
                                  if (!Number.isInteger(Number(hours))) hours = '0'+ Math.floor(hours);
                                
                                  const minutes = momentInSeconds.minutes().toString().length < 2
                                    ? momentInSeconds.minutes().toString().padEnd(2, '0') : momentInSeconds.minutes().toString();
                                
                                  const absolute = hours + minutes;
                                  return absolute;
                                };
                                
                                console.log(parseIsoToAbsolute('PT1H30M'));
                            <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
                            <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
                            <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

                            【讨论】:

                            • 如果您将代码作为 sn-p 插入,您将能够测试该方法并向控制台显示一些输出。
                            • 没问题!刚刚更新了 sn-p 以进行快速测试。
                            【解决方案29】:

                            只有 moment.js 没有任何其他插件

                            moment().startOf('day').seconds(duration).format('HH:mm:ss')
                            

                            【讨论】:

                              【解决方案30】:

                              如果您使用 Angular >2,我制作了一个受 @hai-alaluf 答案启发的管道。

                              import {Pipe, PipeTransform} from "@angular/core";
                              
                              @Pipe({
                                name: "duration",
                              })
                              
                              export class DurationPipe implements PipeTransform {
                              
                                public transform(value: any, args?: any): any {
                              
                                  // secs to ms
                                  value = value * 1000;
                                  const days = Math.floor(value / 86400000);
                                  value = value % 86400000;
                                  const hours = Math.floor(value / 3600000);
                                  value = value % 3600000;
                                  const minutes = Math.floor(value / 60000);
                                  value = value % 60000;
                                  const seconds = Math.floor(value / 1000);
                                  return (days ? days + " days " : "") +
                                    (hours ? hours + " hours " : "") +
                                    (minutes ? minutes + " minutes " : "") +
                                    (seconds ? seconds + " seconds " : "") +
                                    (!days && !hours && !minutes && !seconds ? 0 : "");
                                }
                              }
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2018-11-09
                                • 1970-01-01
                                相关资源
                                最近更新 更多