Moment: 持续时间缺少功能

创建于 2012-10-10  ·  186评论  ·  资料来源: moment/moment

我正在开发一个项目,momentjs对于日期操作确实很有用,所以谢谢。

举一个例子,我们正在某种形式的机票商店。 duration.humanize()函数对我们来说是不精确的。

例如,在12:00出发并在13:30登陆时。 它将舍入到2个小时。 但是,我们需要momentjs中缺少的某种粒度。

人性化可以从最高值开始默认为1级精度。

// 1:30
duration.humanize()
2 hour
duration.humanize({precision: 2})
1 hour 30 minutes
duration.humanize({precision: 3})
1 hour 30 minutes 0 seconds

第二个问题是当数字为0时。Momentjs将其转换为“几秒钟”。 我不确定如何实现,但是具有某种格式会很酷。

// 3 days and 0 minutes
duration.format('D [and] M')
> 3 days and 0 minutes
duration.format('H [and] M')
> 72 hours and 0 minutes
duration.format('H [and] m')
> 72 hours and few minutes

这样,最高值可以映射为格式。 因此,即使有1年,该格式也会告诉我们如何正确显示它。 我很乐意为此提交一个提交,因为它非常有用,当momentjs已经处理过本地化时,必须手动执行它感觉很糟糕。

New Feature

最有用的评论

2019年仍然需要​​此功能。

所有186条评论

对此请求+1

@llacroix ,您是否有兴趣为此编写请求请求?

是的,我会尽力争取时间。 从长远来看,将其添加到momentjs可能会节省自己和其他人的时间。 目前,这迫使我到处乱成一团,这并不完美。 修复momentjs似乎更合适。

但是我们可能应该讨论更多关于应该采用哪种格式的内容。 例如,是否应显示0个值。

4 hours 20 seconds0 days 4 hours 0 minutes 20 seconds

月将是30天,一年365。

以及除了年,月,周,日,分钟,秒和毫秒之外的其他格式。

为此+1
但是,是的,格式化是这里的关键问题。 人性化和格式设置绝对是必需的。
有关人性化行为的一些建议:
// 1:30
duration.humanize();
1小时30分钟
duration.humanize({round:“ hours”})
2小时
duration.humanize({round:“ minutes”})
1小时30分钟
duration.humanize({round:“ seconds”})
1小时30分钟0秒

如果未明确定义倒圆角,我认为其值为零且小于该值的所有单位的最高单位应省略。

// 1小时0分钟45秒
duration.humanize()-> 1小时
// 1小时1分钟0秒
duration.humanize()-> 1小时1分钟
// 1小时1分钟10秒
duration.humanize()-> 1小时1分10秒

另外,“和”分隔符应用于最后一个连接,以空格开头
2个月6天7小时36分钟

这就是我想像的功能默认情况下的行为

这是我对签名和实现的建议。

var duration = moment.duration({
    hours : 1,
    minutes : 0,
    seconds : 20,
    milliseconds : 0
});
duration.countdown(); // 1 hour 0 minutes 20 seconds
duration.countdown(1); // 1 hour
duration.countdown(2); // 1 hour and 0 minutes
duration.countdown(3); // 1 hour 0 minutes and 20 seconds

正如@sylvainpolletvillard所建议的那样,我们可能想要添加一个参数以修剪零值。 也许是这样的。

duration.countdown(3); // 1 hour 0 minutes and 1 second
duration.countdown(3, true); // 1 hour

我们可能还想为后缀添加一个参数,例如moment.fromNow(Boolean)

duration.countdown(3); // 1 hour 0 minutes and 1 second ago
duration.countdown(3, null, true); // 1 hour ago

我们可以轻松地用英语构建它,但是以所有不同语言正确地连接所有这些字符串将非常棘手。

我们可能必须为语言创建回调以自行连接字符串。 这些规则可能非常复杂(匈牙利,我正在看着你)。

我认为传递这些值的最佳方法将是如下所示。

var keys    = [     "h",        "mm",          "s"],
    values  = [       1,           0,           20],
    strings = ["1 hour", "0 minutes", "20 seconds"];

lang.countdown(keys, values, strings, addSuffix);

那么英语翻译将是这样的:

lang.countdown = function (keys, values, strings, addSuffix) {
    var i, output = "";

    for (i = 0; i < strings.length; i++) {
        if (i === strings.length - 1 && strings.length > 1) {
            output += "and ";
        }
        output += strings[i] + " ";
    }
    if (addSuffix) {
        output += "ago";
    }
}

总而言之,这变成了一个非常复杂的添加,将需要33个翻译功能和更多核心代码。 另外,我不确定使用频率如何,因此会给其他所有人带来麻烦。

也许最好将其移至插件?

回到有关格式化持续时间的讨论,我认为,如果有可能这样的话,那将是很好的-

moment.duration(9483000).format('d h m s') // 1 day 2 hours 20 minutes 30 seconds  
moment.duration(9483000).format('h m s') // 26 hours 20 minutes 30 seconds 
//etc...  

也许在format方法中提供一个布尔参数以确定是否显示0个值?

CLDR具有列表格式设置方案和数据,这些列表格式和数据可能可以用于多种语言,但是尽管如此,许多语言可能仍需要自定义回调:

http://cldr.unicode.org/development/development-process/design-proposals/list-formatting

我很喜欢格式功能。 由于实现多种语言的翻译可能非常困难。 使用格式应该很容易实现。

假设您要

moment.duration(9483000).format('d h m s') // 1 day 2 hours 20 minutes and 30 seconds  
// English  => 'd h m [and] s' 1 day 2 hours 20 minutes and 30 seconds
// French   => 'd, h, m [et] s'   1 jour, 2 heures, 20 minutes et 30 secondes
// Russian  => 'd h m [и] s'   1 день 2 часа 30 минут и 30 секунд

不需要特殊的回调,而只是特殊的格式字符串。

建议的duration.countdown()duration.countdown(1)方法正是我想要的(即我现在在自己的代码中正在做的事情)。

同时,有没有办法扩展Duration原型?

持续时间原型通过moment.duration.fnmoment.fn类似。

我去年在#143 /#192上进行过类似的工作。 Tim推荐了一个插件,但我从未花时间去做。

我正要重新启动我的工作。 我不得不更新到新的概念,例如工期对象等。我是这张票和其他票。 现在我在努力是否仍然需要它,如果是的话,我们应该如何实现它。

我不想踩鞋,所以我认识了我能不能帮上忙。 谁正在处理这个问题?

我的代码能够格式化为连续单位和非连续单位,例如:

test.equal(moment([2012, 0, 1]).diff([2011, 0, 1], 'years\\y'), "1y");
test.equal(moment([2012, 0, 1]).diff([2011, 0, 1], 'months[m]'), "12m");
test.equal(moment([2016, 0, 20]).diff([2011, 10, 1], 'months [months] days [days]'), "50 months 19 days");
test.equal(moment([2016, 0, 20]).diff([2011, 10, 1], 'years \\y months \\M days \\d'), "4 y 2 M 19 d");
test.equal(moment([2016, 0, 20]).diff([2011, 10, 1], 'years[y] days[d]'), "4y 80d");
test.equal(moment([2016, 0, 20]).diff([2011, 10, 1], 'years [years] weeks [weeks]'), "4 years 11 weeks");
test.equal(moment([2016, 0, 20]).diff([2011, 10, 1], 'years\\y weeks\\w [and] days [days]'), "4y 11w and 3 days");
test.equal(moment([2016, 0, 20]).diff([2011, 10, 1], 'days\\d'), "1541d");

它不处理诸如'days years'类的不按顺序排列的单位。 它也没有处理删除零值。

看起来很棒,正是我所希望的那种!

这绝对是每个人都需要的功能。

需要这个!

作为某些人的权宜之计,我创建了一个简单的插件,该插件可让您直接从Moment中使用countdown.js

moment("1982-5-25").countdown().toString(); // => '30 years, 10 months, 14 days, 2 hours, 23 minutes, and 50 seconds'

它会传递您传递的任何Countdown选项,例如要使用的单位以及精确度(您可以查看Countdown文档)。 无论如何,插件在这里: https :

@icambron感谢您的参与! 这非常有帮助!

我刚刚开始使用moment.js,很快就遇到了这个确切的问题。 这是我用来解决它的代码:

moment.duration.fn.format = function (input) {
    var output = input;
    var milliseconds = this.asMilliseconds();
    var totalMilliseconds = 0;
    var replaceRegexps = {
        years: /Y(?!Y)/g,
        months: /M(?!M)/g,
        weeks: /W(?!W)/g,
        days: /D(?!D)/g,
        hours: /H(?!H)/g,
        minutes: /m(?!m)/g,
        seconds: /s(?!s)/g,
        milliseconds: /S(?!S)/g
    }
    var matchRegexps = {
        years: /Y/g,
        months: /M/g,
        weeks: /W/g,
        days: /D/g,
        hours: /H/g,
        minutes: /m/g,
        seconds: /s/g,
        milliseconds: /S/g
    }
    for (var r in replaceRegexps) {
        if (replaceRegexps[r].test(output)) {
            var as = 'as'+r.charAt(0).toUpperCase() + r.slice(1);
            var value = new String(Math.floor(moment.duration(milliseconds - totalMilliseconds)[as]()));
            var replacements = output.match(matchRegexps[r]).length - value.length;
            output = output.replace(replaceRegexps[r], value);

            while (replacements > 0 && replaceRegexps[r].test(output)) {
                output = output.replace(replaceRegexps[r], '0');
                replacements--;
            }
            output = output.replace(matchRegexps[r], '');

            var temp = {};
            temp[r] = value;
            totalMilliseconds += moment.duration(temp).asMilliseconds();
        }
    }
    return output;
}

此代码的功能:

d=moment.duration({hours:1,minutes:1,seconds:1});
d.format('HHH:mm:ss');
"001:01:01"
  • 如果在输入模板中省略了一个字符,而后一个字符的值大于通常的最大值,则会在其前面加上前一个字符,例如:
d=moment.duration({days:1, hours:1, minutes: 1});
d.format('H:mm:ss');
"25:01:00"

可能的问题:

  • 对从asXxxx获得的值使用Math.floor,例如:
Math.floor(moment.duration(milliseconds)).asHours()
  • 这意味着,例如,如果持续时间中有分钟或秒的值,但是您要求格式化函数数小时,那么它将不会四舍五入,它将始终四舍五入。

为此请求+1

我个人认为,实现.format()方法比为.humanize()设置一些花哨规则或创建.countdown()方法更有意义。 .format()可以解决95%的问题。

我同意.humanize()应该提供更高的精度,但这应该是另一种功能。

格式化持续时间是必须的。 用格式的字符串转换秒应该很容易。

我尝试了分解代码,但是:
d = moment.duration({天:1,小时:1,分钟:1}); d.format('DH:mm:ss');
“ 1 -215:01:00”

format() +1

作为一个用例,计时考试(3小时)中使用的持续时间可以很容易地设置为hh:mm(:ss)左右的格式,这样会更容易得多。 现在,在我迷上香草js之前,很难在瞬间做同样的事情:)

+1持续时间格式!

这是我使用的快速修复方法:

moment.duration.fn.format = function(){
    str = ""
    if(this.days() > 1) str = str + Math.floor(this.days()) + "d "
    if(this.hours() > 1) str = str + Math.floor(this.hours()) + "h "
    if(this.minutes() > 1) str = str + Math.floor(this.minutes()) + "m "
    if(this.seconds() > 1) str = str + Math.floor(this.seconds()) + "s "
    return str
    }

:+1:为duration.format()

:+1:也适用于duration.format()

此PR的状态如何? 离它远吗?

Code Bounty

我已经离开了一段时间...我创造这个问题已经快一年了。 我会尝试的。 我将分叉js,并在我有一些要测试/审查的内容时立即更新此问题。 我必须在两天内为考试做准备。 因此,不太可能在两天内显示任何内容。 也就是说,我会继续努力。

@llacroix谢谢:)

:+1:为duration.format()

 moment.duration.fn.format =函数(零,twoDigit){
 var hours = this.hours(),minutes = this.minutes(),seconds = this.seconds();
 var displayFormat ='',zerosFormat = twoDigit? '00':'0',padLeft = twoDigit? -2:-1;
 如果(小时||零){
 displayFormat + =(zerosFormat + hours).slice(padLeft)+'h';
 }
 如果(分钟||零){
 displayFormat + =(zerosFormat +分钟).slice(padLeft)+'min';
 }
 如果(秒||零){
 displayFormat + =(zerosFormat +秒).slice(padLeft)+'s';
 }
 返回$ .trim(displayFormat);
 }

+1持续时间格式。

+1持续时间格式

+1持续时间格式

我确实需要全面的持续时间格式,因此我在这里和StackOverflow上回顾了线程,今天坐下来实施它。

我仍在处理一些次要的细节,但核心工作已经完成且扎实。 在接下来的几天中,我将在此处发布代码,规范和示例。 基本思想是,您可以具有任意持续时间,并使用类似于时刻日期格式字符串的字符串对其进行格式化,例如。 duration.format(“ d [d] hh:mm:ss”)-> 2d 03:47:24

您也可以在最终值上定义任意十进制精度,例如。 duration.format(“ h [hrs]”,3)-> 42.384小时

+1为duration.format

我发布了我的moment.duration.format插件:
https://github.com/jsmreese/moment-duration-format

测试用例和一些示例在项目中。
我的插件依赖lodash和underscore.string。

+1 duration.format()

这张票已经在一年多以前开放了。 我怀疑它是否会实施。

@ Maxwell2022大约一周前,我发布了一个moment.duration.format插件:
https://github.com/jsmreese/moment-duration-format

那对你有用吗?

也为此+1。 在其他方面比较全面的库中似乎有一个非常明显的遗漏。

https://github.com/rmm5t/jquery-timeago可能是一个很好的模板,可以帮助我们在瞬间实现此目标...

@schmod我上个月发布了一个moment.duration.format插件:
https://github.com/jsmreese/moment-duration-format

这对您的用例有用吗?

:+1:!

这将对我有效(但不会超过24小时):

moment.duration.fn.format = function(format) {
  return moment(this.as('milliseconds')).format(format);
}

@jsmreese您依赖于https://github.com/jsmreese/moment-duration-format是真正的热门。 我们已经使用了下划线,仅凭此小功能我不能证明切换到LoDash是合理的。 如果您的插件独立于这两者,那么对于许多人来说,这将使其成为更可行的选择。

@wleeper绝对同意。

我的环境恰好使用LoDash和Underscore.String,所以我使用了那些库中的方法-几个月前我需要第一个版本,只是想将其实现并发布。

我将很快删除那些依赖项。

@wleeper Underscore和LoDash旨在相互兼容。 只要@jsmreese没有在

@ chall8908这东西,和@wleeper是对的-我_am_使用不是下划线构建的一部分LoDash的特点。

我已经删除了Underscore.String依赖关系,并且我在致力于Underscore兼容性。

尽管矩持续时间格式插件解决了这些问题之一,但我认为我们需要一种可跨区域使用的方法(诚然,要困难得多)。

我认为我们需要着手实施#1241,这将在呈现人类可读的日期,相对日期,持续时间和跨区域列表方面打开很多大门。 如果Moment可以访问CLDR语言数据,则formatDuration实现相当简单。

jQuery的Globalize库正在解决许多相同的问题,与它们进行协作似乎合乎逻辑。 Twitter还已经拥有一个非常全面的,可以完成很多这类事情……

好的,这是CLDR之上的一个可实现的API。 你怎么看?

duration:human(bool) // future/past dep/indep
duration:human({
  with(=min+max): 'hours'|'minutes'|'seconds',
  min: 'hours',
  max: 'days',
  float: bool,
  length: "long|short|narrow",
  abs: bool
})
  • 最小值:最小单位是多少? min:天,表示不说小时,分钟,秒,但是如果持续时间短于一天,则四舍五入到天
  • max:要使用的最大单位是多少。 max:天,表示不使用月和年,而是使用各自的天数
  • 长度:代币数量:英语天与天
  • ABS:与过去/过去无关

:+1:+1

:+1:

+1持续时间格式

+1持续时间格式

+1

+1

+1

想要这样显示某事的运行时间。

+1

https://github.com/jsmreese/moment-duration-format

NPM上发布了矩持续时间格式的版本1.2.1。
它在Node.js和浏览器中均起作用。
它确实取决于Lo-Dash或Underscore,但是现在已经过测试并且可以同时使用。
原始的Underscore.String依赖关系已删除。

一旦当前的Bower软件包注册/注销问题解决,我将立即将此版本发布给Bower。

+1表示持续时间格式

希望此成为图书馆的一部分。

+1

+1

+1

:+1:

+1为duration.format()

+1

哦,是的,我肯定会参与其中,至少能够执行moment.duration(3, 'seconds').get('ss')来输出前导零值。

此请求的状态如何? 需要什么帮助才能取得进展?

@oncletom
存在: https :
如果您不介意对Lo-Dash或Underscore的依赖,则可以执行您想要的操作。
不久的一天,我将花一些时间删除该依赖项...

humanize不在https://github.com/jsmreese/moment-duration-format/不在stdlib中时,我感到很惊讶。 我觉得这违反了最不惊奇的原则。 至少,应该可以恢复为简单的数字格式:

moment.duration(123, "minutes").format();
// "2:03:00"

目前,我正在使用:

moment.utc(moment.duration(300 * 1000).asMilliseconds()).format("HH:mm:ss.SSS")
// 00:05:00.000

希望很快将其作为moments.js的一部分

+1

+1

在相关注释上, duration.toString()返回[Object object] 。 它不应该返回humanize()吗?

+1希望对此有更多控制权。

+1

刚刚发布的Moment Duration Format 1.3.0,删除了以前对Lo-Dash或Underscore的依赖。 现在唯一的依赖是Moment.js本身。

https://github.com/jsmreese/moment-duration-format/

@jsmreese好男人! :啤酒:

@jsmreese很酷。 !
为什么这不是moment.js本身的一部分,我不明白。 没有精确度,人性化不是那么有用,为什么我要舍入1小时30分钟到1小时?

+ 1,jsmreese的插件工作出色,但如果它是moment.js的一部分,那就太好了。

+1。 此功能应内置并人性化。

+1为duration.format

@jsmreese在一年前发布了他的插件,并且此问题在两年前就已打开。 @timrwood @ichernev我们可以将其添加到主要的moment.js库中吗?

+1

+1

:+1:为duration.format

+1

:+1:

+1

它的当前状态是什么?

也许维护者正在等到我们达到1000或除夕之夜? @icambron

@gkatsanos-我不再主动帮助维护Moment(我一直只是一个助手),但是我的建议是经过充分测试的拉取请求。 肯定有人要求这种意愿进行实际编码。

@icambron这个已经作为插件存在了。还有什么要做的呢?
谁是维护者?

@icambron您能否指向插件?

它似乎是一个形状非常好的插件。 除了它取决于lodash而不是underscore ,是否还有其他事情阻止它作为PR ..似乎是从lodashunderscore的端口@jsmreese

@alexanderbeletsky @gkatsanos实际上,我刚才删除了lodashunderscore依赖项。

Moment.js核心中包含我的插件的主要障碍之一是缺乏完整的i18n支持。

就我个人而言,这是我的主要担忧。 支持的多种语言对我来说是一件大事,我不愿意遇到功能A以任何语言工作而功能B只支持英语的情况。

@jsmreese也许是在您的存储库中创建一些定义明确的任务,这些任务到底需要做些什么-我一定会帮助您。

@mattgrande @alexanderbeletsky格式标记已经可以自定义,并且格式模板是任意的,因此这不是问题。

默认格式模板未进行任何本地化,并且您无法本地化小数点或在值上添加任何形式的本地化数字格式。 这就是我头上所有的东西。

:+1:

+1 duration.format!

oo...。

只是留意一些事情,因为这里有大约一百万条评论。 我不是维护者,也不再参与这个项目,但是我很确定两件事:

  1. 所有人,您都可以使用@jsmreese的插件。 看起来不错! 插件是好东西! ( @jsmreese ,如果您愿意,可以将其添加到具有PR的文档中的Moment插件列表中:https://github.com/moment/momentjs.com)
  2. 除非有人a)将其国际化,b)将测试集成到Moment的测试中,以及c)提交PR,否则它不会包含在Moment的核心中。 除非有人这样​​做,否则

+1持续时间格式

+1 duration.format!

+1持续时间格式

+1持续时间格式。 我们的情况是我们希望提供一种函数,该函数可以传递几秒钟的时间,并提供一个字符串来格式化它们。 现在,我们使用moment.startof(“ w”)。add(“ s”,nrOfSeconds).format(customFormatString);

不幸的是,就在上周,由于startof(“ w”)是星期日,这产生了一个错误,在星期天是夏令时的时间,所以我们在那里错过了一个小时。 当然,我们可以使用isDSTShifted()进行检查,但是不必将持续时间转换为日期来格式化它仍然很棒。

+1持续时间格式

+1持续时间格式

duration.format +1

+1为duration.format

我们是否可以关闭此线程,因为显然没有人+1实际读取此线程?

2015年6月10日,星期三,08:30 SamFromDaUk [email protected]写道:

+1为duration.format

-
直接回复此电子邮件或在GitHub上查看
https://github.com/moment/moment/issues/463#issuecomment -110751635。

还是解决?

乔治,我认为那些加+1的人暗含不同意,并且
只是想要这些功能。

如果通知让您感到烦恼,请考虑取消订阅
线。
2015年6月11日00:07,“ George Katsanos” [email protected]写道:

还是解决?

-
直接回复此电子邮件或在GitHub上查看
https://github.com/moment/moment/issues/463#issuecomment -110767322。

github没有投票功能的全部原因(据我了解)是因为它不鼓励讨论。

您可以暗含不同意的全部内容,这无济于事。 如果您不同意那很好,请通读线程并提供您的论据(特别是,您认为未充分考虑的任何新论据或任何观点)。

我仍然订阅,因为我认为尚有一些有趣的论点,我希望听到他们的意见,但团队不应该屈服于同龄人的压力。

我可以确认上述插件@icambron正常工作。

如果您像我一样,则需要一个具有更广泛输出的.fromNow() (例如亚马逊的运输倒计时)。 这样做的方法如下:

// include the plugin
var cutoffDate = moment().add(3, 'hours'); // some date in the future that we're counting down to
var now = moment();
var output = moment.duration(cutoffDate.diff(now)).format('h [hours] m [minutes] s [seconds]');
// "3 hours 0 minutes 0 seconds"

是的,我也要说清楚-moment.duration()。format()可与此插件一起使用: https :

如果您正在使用流星,请选择oaf:moment-duration-format

这似乎对我不起作用,我在两次之间使用了时刻.diff,这确实有效,问题是当它位于“ pm”和“ am”之间时,比如说我在晚上9点旅行并着陆凌晨2点,我应该获得正确的时间。

@ Markj89,您需要打开一个stackoverflow主题。

+1

+1

+1

:+1:

结束此问题时+1。 使用插件是一个可靠的解决方案。

+1

+1

.format()上+1

+1,四年后仍未实施? :D

+1

顺便说一句。 我认为也应该解析人性化格式。 例如,解析7 days and 5 hours并不难...

只是想强调@jsmreese插件效果很好!

:+1:

+1持续时间格式

+1持续时间格式

+1持续时间格式

+1持续时间格式

:+1:

我将以#1048结尾。 这并不意味着它已经消失了,我们只是遇到了两个已经存在数年的问题,并且都归结为“进行持续时间格式化”。 另一个则更清楚地解释了这一点。

+1持续时间格式

+1持续时间格式

+1

使用.localeData()。relativeTime(45,true,'mm')并获得45分钟,以此类推;)

+1确实有很多关于此的讨论,但尚未实现。 甚至还有单独的软件包用于此https://github.com/jsmreese/moment-duration-format

要以任何格式显示持续时间,只需将持续时间转换为ms然后转换为矩:
moment(duration.as('milliseconds')).format('HH:mm:ss')

谢谢! 这是在文档中吗? 我没看到...

这不在文档中,因为它不起作用。 这是一种使用unix纪元将毫秒解释为自该纪元以来的时间点的黑客。 因此,如果您的持续时间为24小时或更长,它就会崩溃。

关于此代码的几件事:

  1. hh令牌是要与AM / PM一起使用的令牌,因此您的持续时间最多只能达到12

  2. 即使您使用的HH令牌最多可以使用23个,但您的持续时间也不能超过23:59:59.999,因为事情会延续到下一个日期

  3. 在编写此代码时,它将仅在UTC中的服务器上工作。 在不同时区的任何浏览器都会产生意外结果。

如果要使用此技巧,应将其写为:

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

但是,正如我指出的那样,这仅在您的时长少于24小时的情况下才有效。 在那上面,回到正方形1。

谢谢。 今天我花了一段时间才弄清楚一个人可以将.minutes().seconds() 。 称我为愚蠢的人,但是从文档中对我来说, .seconds().asSeconds()之间的区别马上就不明显了……但是现在我看到它实际上就在那里! :)

例如: console.log(duration.minutes()+":"+duration.seconds());

我会坚持使用这种方法。

@elasticsteve如果秒数部分少于十,您可能还想在其前添加零。 :眨眼:

@butterflyhug @elasticsteve实际上是我想要使用format主要原因。 就我而言,这是一个简单的短时计数器,因此@maggiepint的解决方案足以满足我的需求。
moment.utc(duration.asMilliseconds()).format('HH:mm:ss')

@sagivo好点! 现在, @ maggiepint解决方案看起来更具吸引力。 我的服务器还是UTC。

当然可以,我完全理解。 我还在生产代码中使用了该技巧。 但是我不建议将其作为一般解决方案(除了一些特定的用例之外),因为在很多情况下,它都会严重失败。 (例如,负持续时间是另一个重要的失败案例,尚未明确提及。)

+1

+1 duration.format()!!!!!!!!!

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1难以调试的持续时间

+1

您可以轻松地执行以下操作:

    var duration = moment().add(5, 'days') -  moment().local();
    var s = Math.floor( (duration/1000) % 60 );
    var m = Math.floor( (duration/1000/60) % 60 );
    var h = Math.floor( (duration/(1000*60*60)) % 24 );
    var d = Math.floor( duration/(1000*60*60*24) );
    return d + ' days ' + h + ' hours ' + m + ' minutes ' + s  + ' seconds before the deadline.';   
    // 4 days 23 hours 59 minutes 59 seconds before the deadline.

请求一个用户twitter @Toon_Ladyboy

您可以轻松地执行以下操作:

    var duration = moment().add(5, 'days') -  moment().local();
    var s = Math.floor( (duration/1000) % 60 );
    var m = Math.floor( (duration/1000/60) % 60 );
    var h = Math.floor( (duration/(1000*60*60)) % 24 );
    var d = Math.floor( duration/(1000*60*60*24) );
    return d + ' days ' + h + ' hours ' + m + ' minutes ' + s  + ' seconds before the deadline.';   
    // 4 days 23 hours 59 minutes 59 seconds before the deadline.

难看,但有效。

2019年仍然需要​​此功能。

人性化中的一个简单参数,例如humanize(precise: true) ,它将绕过所有舍入将足以使每个人高兴。 此外,舍入是很难实现的部分。 剩下的就是转换持续时间,就像使用format()完成的任何其他格式化一样简单。

有一个很棒的moment方法,称为fromNow() ,它会以易于阅读的形式返回特定时间的时间,如下所示:

moment('2019-04-30T07:30:53.000Z').fromNow() // an hour ago || a day ago || 10 days ago

或者,如果您希望在两个特定的日期之间使用它,则可以使用:

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.from(b); // "a day ago"

摘自文档:

可以重新打开吗? 这是非常基本的功能。

以我为例,我找到了一个可以解决我问题的软件包:
https://github.com/EvanHahn/HumanizeDuration.js

也许对其他人也有用。 :)

2019年7月,此功能仍然不可用。

2019年7月,此功能仍然不可用。

还没有尝试过,但是我注意到了!
npm install moment-duration-format

https://github.com/jsmreese/moment-duration-format

2019年9月仍然正式错过此功能

d.format('H:mm:ss');
"1:01:01"

还希望它可以具有此功能

d.format('D-H:mm:ss'); // existence of D will mod hours to 24
"999-23:59:59"

万一有人想知道为什么关闭它: https :

这绝对不是理想的选择,但是我最终做了这样的解决方法。 我有一个带有倒计时的duration对象,用于在用户不活动后将其注销,并希望格式化剩余的时间。

// What I did:
private getTimeString(duration: moment.Duration): string {
    const time = moment()
      .seconds(duration.seconds())
      .minutes(duration.minutes());

    return time.format('mm:ss');
}

// What I'd rather do (as many others have mentioned)...
private getTimeString(duration: moment.Duration): string {
    return duration.format('mm:ss');
}

我的骇客解决方案:

import moment from 'moment';

const formatInt = (int: number): string => {
  if (int < 10) {
    return `0${int}`;
  }
  return `${int}`;
};

export const formatDuration = (time: string): string => {
  const seconds = moment.duration(time).seconds();
  const minutes = moment.duration(time).minutes();
  const hours = moment.duration(time).hours();
  if (hours > 0) {
    return `${formatInt(hours)}:${formatInt(minutes)}:${formatInt(seconds)}`;
  }
  if (minutes > 0) {
    return `${formatInt(minutes)}:${formatInt(seconds)}`;
  }
  return `00:${formatInt(seconds)}`;
};

2020年

我使用以下方法,这可能对其他人有用:)

function formatDuration(duration, format) {
  const date = moment().startOf('day');
  return date.add(duration).format(format);
}

(我仅用于格式化介于00:00和23:59之间的持续时间)

还需要这个

这些“获取”有助于以您想要的方式进行格式化:

  duration.get('years')
  duration.get('months')
  duration.get('days')
  duration.get('hours')
  duration.get('minutes')
  duration.get('seconds')

我的工作:

const formatDuration = ms => {
  const days = Math.floor(ms / 8.64e7);
  const msOnLastDay = ms - days * 8.64e7;
  return (days < 10 ? "0" + days : days) + ":" + moment.utc(msOnLastDay).format("HH:mm:ss.SSS");
};
formatDuration(5)
"00:00:00:00.005"
formatDuration(500)
"00:00:00:00.500"
formatDuration(50000)
"00:00:00:50.000"
formatDuration(5000000)
"00:01:23:20.000"
formatDuration(500000000)
"05:18:53:20.000"
// for reference
JSON.stringify(moment.duration(500000000)._data, null, 2)
"{
  "milliseconds": 0,
  "seconds": 20,
  "minutes": 53,
  "hours": 18,
  "days": 5,
  "months": 0,
  "years": 0
}"

2019年7月,此功能仍然不可用。

还没有尝试过,但是我注意到了!
npm install moment-duration-format

https://github.com/jsmreese/moment-duration-format

这工作得很好:)

游戏结束了:)

谢谢,谢谢!!!


De:Aleksey Makas [email protected]
Enviado:sexta-feira,2020年9月9日11:03
段落:moment / moment
抄送:Douglas Aguiar [email protected] ; 发表评论[email protected]
Assunto:回复:[moment / moment]持续时间缺少功能(#463)

游戏结束了:)

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub https://github.com/moment/moment/issues/463#issuecomment-706200427上查看或取消订阅https://github.com/notifications/unsubscribe-auth/AGD22DRNGNIQMOJFQY7VW3DSJ4J4VANCNFSM4ABRUZLA

此页面是否有帮助?
5 / 5 - 1 等级