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


211

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

我希望能够执行以下操作:

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

另外,如果还有其他任何可以轻松容纳这种功能的库,我会对建议感兴趣。

谢谢!


5
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:ss00:00:23在我之前的示例中给出。因此,在“小时”部分输入的是错误的
字母

Answers:


55

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

http://countdownjs.org/https://github.com/icambron/twix.js还有一些其他可能有用的


4
我也期待持续时间格式。现在来看一下countdownjs,但是twix似乎只做“智能”格式,没有太多定制。
mpen

2
尽管twix努力进行智能格式化,但它具有许多格式化选项,直至涉及的令牌:github.com/icambron/twix.js/wiki/Formatting。免责声明:我是twix的作者。

3
Countdown.js非常好,作者非常有帮助(由于我提出的一些建议,他当天发布了两个版本)!
Ohad Schneider

5
我投票失败,因为此答案中链接的github问题只是永无休止的观点,愿望和言论,无处可

29
为什么它不能与库中其他地方使用的其他.format相同?这是精神错乱。5年了,还没有完成?真?!
kristopolous

164
// 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);

看看JSFiddle


3
好方法。虽然如果我也想显示天数则不起作用:(需要DDD HH:mm:ss.SSSDDD一年中的某天)1在需要时显示0。有什么快速解决办法吗?
Andrew Mao

1
没有简单的方法。我做了这个 jsfiddle.net/fhdd8/14,这可能是您所做的,但是我认为当下没有任何事情可以做到这一点
David Glass

49
将10万亿毫秒显示为mm:ss毫无意义
Pier-Luc Gendreau 2014年

28
这在24小时后无法正常工作(即,如果我想显示117小时)。否则很好的解决方案!
Phil

1
@Phil如果要显示日期,可以使用“ D”或“ DD”。
Vinay

71

将持续时间转换为ms,然后转换为矩:

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

14
因此,如果您的持续时间超过24h,则此方法将
无效。.24h

4
@ S.Robijns是一个有用的观察,但仅是为了向其他人强调-这的预期行为.format('HH:mm:ss')查看文档
davnicwil

1
这是最好的答案!
Magico

44

使用此插件的Moment Duration Format

例:

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

1
该格式无法正常工作,持续时间方面很好,但是如果我指定hh:mm:mm并且仅显示10秒,那么它会显示10而不是00:00:10(即使在启用forcelength的情况下)如果未格式化...则应将其称为其他格式,标准化的。
Piotr Kula 2015年

9
@ppumkin我知道这很旧,但是如果您指定{ trim: false }它将停止这种行为。
卡洛斯·马丁内斯

3
这就是我更喜欢使用的方式:假设您有持续时间,就像const duration = moment.duration(value, 'seconds');可以使用以下命令格式化我一样: moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
Evgeny Bobkin

1
@EvgenyBobkin如果您的时间超过一天,将无法正常工作,但是图书馆会进行处理
reggaeguitar

16

使用以下代码行:

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

8
如果持续时间大于86400英寸(即24小时),则将无法使用。
罗伦佐·塔森

在excel中也是如此,它将在24小时后翻转。如果您知道24小时限制,这是一个很好的解决方法。
Eman4real

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

1
通常,如果答案包括对代码意图的解释,以及为什么不引入其他代码就能解决问题的原因,则答案会更有帮助。(此帖子已由至少一个用户标记,大概是因为他们认为应删除无解释的答案。)
内森·塔吉

1
不论是否解释,这就是为我做的。谢谢:)
dmmd

不需要解释。Moment.js文档可以显示该解决方案是如何实现的。
coffekid

2
无用。像该问题的大多数其他答案一样,返回的部分持续时间不是总小时数。例如,在duration.duration({days:2,hours:12})持续时间内返回12:00
Neutrino

1
moment.duration(diff).asMilliseconds()过多。您可以使用diff,它已经以毫秒为单位。
kristopolous

12

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

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

这将改善@Wilson的答案,因为它不访问私有内部属性_data。


谢谢@TaeKwonJ​​oe
Kamlesh

11

您不需要.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

2
但是,如果duration.seconds()小于10,则不会包括前导零
。– carpiediem

如果您的秒数超过一个小时,该怎么办?那么您有60秒钟以上的时间可以吗?
shaedrich '18

前导零有效,但duration = moment.duration(7200, 'seconds'); withPadding(duration);会说“ 00:00”。
shaedrich '18

@shaedrich我再次更新了我的答案以包含小时数;如果您还需要几天,几周或几天,也可以将它们添加到阵列中
ni-ko-o-kin

1
if (duration.asDays() > 0) { return 'at least one day';-我读得正确吗?
斯蒂芬·保罗

8

我用:

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

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


大!这就是行得通...您是如何想到这个的:)
vanthome

4
避免使用此解决方案,它_data是一种内部属性,并且可能在没有警告的情况下进行更改。
德鲁斯卡

1
不幸的是,它不能一直按预期运行:moment(moment.duration(1200000)._data).format('hh:mm:ss')将返回12:20而不是00:20
Anna R

2
@AnnaR h的范围是1-12,所以这是可以预期的。H改为使用文档-小时令牌
barbsan

这是错误的,不仅您忽略了DAYS,而且1day和1hour将显示为01:00。另外你完全忽略的时区,一个更好的解决方案,但也不是一个完整的人会是 moment.utc(...).format("HH:mm");
吉尔Epshtain

5

如果差异是片刻

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

面对时区等,这似乎并不可靠。你在生产中使用这个吗?
基思(Keith)

这个问题没有提到时区。
基兰(Kieran)2013年

3
每个人都住在一个时区。时刻(0)是否始终在每个时区都注册为12:00 AM?
基思(Keith)

我只是问您答案中的代码是否有效,因为我对此表示怀疑。我已经用许多编程语言编写了很多处理日期的代码。根据我的经验,您的代码似乎只能在某些时区工作-但我问的是因为也许我不知道Javascript如何表示Unix时代附近的日期。
基思(Keith)

1
第二行会从时间开始(1970年)开始。这不会。
kumarharsh

5

如果您愿意使用其他JavaScript库,则numeric.js可以按以下格式设置秒数(例如1000秒):

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

肯定要走的路。如预期的那样。
Piotr Kula 2015年

4

在以下情况下,我使用经典格式功能:

var diff = moment(end).unix() - moment(start).unix();

//use unix function instead of difference
moment.unix(diff).format('hh:mm:ss')

这是骇客,因为将时间差异视为标准时刻,即较早的日期,但对我们的目标而言并不重要,您不需要任何插件


4

如果必须显示所有小时数(大于24),并且如果不需要在小时前显示“ 0”,则可以使用一小段代码完成格式化:

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

4

根据ni-ko-o-kin的回答

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

我认为它不是很可读。您想在这里解决什么问题?你的用例是什么?
ni-ko-o-kin

我再次更新了答案以处理一天以上的时间。它适合我的用例。
ni-ko-o-kin

2
问题在于,在大多数情况下,您的解决方案并不理想,因为它包含过多的前导零。谁想要返回“ 00:00:00:00:01”?我的解决方案是“可伸缩的”,并根据需要添加了尽可能多的前导零。
shaedrich '18

完美运作。非常简单的输出。如果没有几天,就会有好几天没有零点显示等
哈桑旋塞阀Ozalp

3

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

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");
}

3

如果使用角度,则将其添加到过滤器中:

.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>

确实很好。我一直在寻找这样的“漂亮格式”。谢谢!
riketscience

3

我的解决方案不涉及任何其他库,并且适用于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))

1

原生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;
}

1

使用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');

0
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 D 14小时00分00秒


0
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

0

您可以使用digit.js设置持续时间的格式:

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

0

这可以用来获取前两个字符(小时)和后两个字符(分钟)。相同的逻辑可以应用于秒。

/**
     * 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>


如果将代码作为摘要插入,则将能够测试该方法并将一些输出显示到控制台。
DJDaveMark

当然可以!刚刚更新了代码段以进行快速测试。
何塞·路易斯·Raffalli

0

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>


0

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

首先,您需要导入momentmoment-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。Moment.js格式无法正常运行。

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

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

好吧,我们现在早上8:00。如果您希望整点时间是上午8点而不是8:00,我们需要进行RegExp

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

0

我需要执行此操作,以显示这种格式的小时数。起初我尝试了这个。

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

希望能有所帮助。在评论中留下任何问题。;)


-1

如果您使用Angular> 2,我会根据@ hai-alaluf的答案创建一个Pipe。

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 : "");
  }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.