如何在moment.js持续时间上使用format()函数?

271

我是否能够在持续时间对象上使用 moment.jsformat 方法?我在文档中没有找到它的任何信息,并且似乎也不是持续时间对象的属性。

我想要做这样的事情:

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

另外,如果有其他能够轻松实现此类功能的库,我会对推荐很感兴趣。

谢谢!


9
moment.utc(duration.asMilliseconds()).format('hh:mm:ss'); “duration”是一个向量。将其尾部放在原点上,您可以使用日期格式化来得到“hh:mm:ss”。 - Paul Williams
1
moment.utc(moment.duration(23, 'seconds').asMilliseconds()).format('hh:mm:ss') => "12:00:23" 不太好用 - goldenratio
2
啊,我找到问题了,在我的先前示例中,HH:mm:ss会给出00:00:23。所以只是小时部分的大小写错误。 - goldenratio
1
对于那些想以可读的方式显示持续时间的人,请使用:moment.duration(diff_ms).humanize(); - Rafe
31个回答

216
// 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.asMilliseconds()).format("HH:mm:ss.SSS");
alert(f);

点击查看JSFiddle


3
不错的方法。但是如果我想显示天数,它就不起作用了:DDD HH:mm:ss.SSS(其中DDD表示一年中的第几天)会显示1,而我想要的是0。有什么快速解决方法吗? - Andrew Mao
1
没有简单的方法。我做了这个 http://jsfiddle.net/fhdd8/14/,这可能是你所做的,但我不认为 moment 有任何可以直接完成这个任务的东西。 - David Glass
56
把10亿亿毫秒显示为mm:ss没有任何意义。 - Pier-Luc Gendreau
41
这个方案不能超过24小时(例如,如果我想显示117小时)。否则是个好的解决方案! - Phil
1
这个答案解释了如何显示格式化的MomentJS MOMENT,而不是问题所述的DURATION。 - RavenHursT
显示剩余7条评论

105

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

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

28
如果持续时间超过24小时,这种方法就不起作用了。24小时会被重置为0小时。 - S. Robijns
6
@S.Robijns提供了一个有用的观察,但是为了强调给其他人看,这确实是.format('HH:mm:ss')预期的行为。请参阅文档 - davnicwil

60

4
我也期待时间格式化功能。现在看了一下countdownjs,但twix似乎只做“智能”格式化,没有太多定制化。 - mpen
2
虽然Twix努力进行智能格式化,但它有许多格式选项,甚至可以涉及到令牌:https://github.com/icambron/twix.js/wiki/Formatting。免责声明:我是Twix的作者。 - user24359
3
Countdown.js非常优秀,作者也非常乐于助人(他因为我提出的建议在同一天内发布了两个版本)! - Ohad Schneider
5
我要点踩这个回答,因为其中链接的 Github 问题只是一个永无止境的意见、愿望和抱怨流,没有任何实质性进展。这个问题已经持续了4年,没有任何有用的结果。 - bmaggi
41
为什么不能与库中其他地方使用的.format完全相同?这太疯狂了。已经五年了,还没有完成?真的吗?! - kristopolous
显示剩余3条评论

49

1
那种格式化方式无法正常工作,持续时间方面是好的,但如果我指定 hh:mm:mm 并且只有10秒钟,它会显示 10 而不是 00:00:10(即使使用了 forcelength)。如果这不是格式化问题...那么它应该被称为其他名称,格式应该标准化。 - Piotr Kula
13
如果你指定 { trim: false } ,它将停止这种行为。 - Carlos Martinez
3
假设您有一个持续时间,比如 const duration = moment.duration(value, 'seconds');,那么可以使用以下格式进行格式化:moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString(); - Evgeny Bobkin
2
@EvgenyBobkin 如果你的持续时间超过一天,那么这种方法就不起作用了,但是库会处理它。 - reggaeguitar

30

使用以下代码行:

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

18
如果持续时间大于86400秒(即24小时),这将无法正常工作。 - Lorenzo Tassone
在Excel中也是一样的,它会在24小时后翻转。如果您知道这个24小时的限制,这是一个很好的解决方法。 - Eman4real
当我使用 .utc 时,时间差太多了。为什么? - Crystal

16
var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");

1
通常情况下,如果答案包含代码的意图和解决问题的原因,而不会引入其他问题,那么这样的答案会更有帮助。(此帖子被至少一个用户标记,可能是因为他们认为没有解释的答案应该被删除。) - Nathan Tuggy
1
无论是否有解释,这就是为我所做的。谢谢 :) - dmmd
Moment.js文档可以展示如何实现这个解决方案。 - coffekid
4
无用。与此问题中其他大多数答案一样,返回的持续时间中包含部分小时而非总小时数。例如,对于 moment.duration({days: 2, hours: 12}) 的持续时间,返回的是 12:00。 - Neutrino
1
moment.duration(diff).asMilliseconds()这样写有点多余。你可以直接使用diff,因为它已经是毫秒了。 - kristopolous

15

对于我的特定用例来说,最好的情况是:

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

这比 @Wilson 的回答更好,因为它不访问私有内部属性 _data。


14

你不需要使用.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

3
如果duration.seconds()小于10,这将不包括前导零... - carpiediem
如果你有超过一个小时的秒数会发生什么?那么你是否可以拥有超过60秒的时间呢? - shaedrich
前导零可以正常工作,但是 duration = moment.duration(7200, 'seconds'); withPadding(duration); 会显示为“00:00”。 - shaedrich
@shaedrich 我更新了我的答案,现在包括小时;如果你需要天、周等,你也可以将它们添加到数组中。 - ni-ko-o-kin
@ni-ko-o-kin 我对这个解决方案的问题是,我可能会输入“1”或“604800”。两者都应该有正确的结果,但没有前导的“00:”。 - shaedrich
1
如果(duration.asDays() > 0){返回“至少一天”;- 我读对了吗? - Stephen Paul

9

作为工作要求,我需要这样做以显示这种格式的小时数。 起初我尝试了这个方法。

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

如果totalMilliseconds894600000,则返回249:30:00。 希望这有所帮助。在评论区留下任何问题。;)

“toFixed()”不会四舍五入数字吗?例如:“76.35”将变为“77”,而您想要的是“76”,然后将小时和分钟附加到其中。我使用了“var hours = Math.floor(moment.duration(totalMilliseconds).asHours())”。您代码中的其他部分都很好。感谢您的回答。 - Craig

8

我使用:

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

我得到了变量str中的"09:30"。


太棒了!这个真的可以用...你是怎么想出来的呢 :) - vanthome
5
避免使用这个解决方案,"_data" 是一个内部属性,可能会在没有警告的情况下更改。 - Druska
1
不幸的是,它并不总是按预期工作:moment(moment.duration(1200000)._data).format('hh:mm:ss')将返回12:20而不是00:20。 - Anna R
2
@AnnaR h 的范围是1-12,所以这是可以预料的。请使用 H 代替 文档 - 小时标记 - barbsan
这是错误的,不仅忽略了DAYS,所以1天和1小时将显示为01:00。此外,您完全忽略了时区,一个更好的解决方案,但也不是完整的解决方案,将是moment.utc(...).format("HH:mm"); - Gil Epshtain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接