获取两个日期时间之间的时差

我知道我可以做任何事情,还有一些更多的时间和时间。 但令人尴尬的是,我很难尝试做一些看起来很简单的事情:两次之间的区别。

例:

var now = "04/09/2013 15:00:00"; var then = "04/09/2013 14:20:30"; //expected result: "00:39:30" 

我试过了:

 var now = moment("04/09/2013 15:00:00"); var then = moment("04/09/2013 14:20:30"); console.log(moment(moment.duration(now.diff(then))).format("hh:mm:ss")) //outputs 10:39:30 

我不明白那里的“10”是什么。 我住在巴西,所以我们是utc-0300,如果这是相关的。

moment.duration(now.diff(then))是一个具有正确内部值的持续时间:

  days: 0 hours: 0 milliseconds: 0 minutes: 39 months: 0 seconds: 30 years: 0 

所以,我想我的问题是:如何将一个momentjs持续时间转换为一个时间间隔? 我当然可以使用

 duration.get("hours") +":"+ duration.get("minutes") +:+ duration.get("seconds") 

但我觉得有一些更优雅的东西,我完全失踪了。

更新
仔细观察, now上面的例子是:

 Tue Apr 09 2013 15:00:00 GMT-0300 (E. South America Standard Time)…} 

moment(moment.duration(now.diff(then)))是:

 Wed Dec 31 1969 22:39:30 GMT-0200 (E. South America Daylight Time)…} 

我不知道为什么第二个值是在夏令时(-0200)…但我相信我不喜欢日期:(

更新2

嗯,值为-0200可能是因为31/12/1969是白天时间被使用的日期…所以那就是。

这种方法只有在总时间少于24小时的情况下才能使用:

 var now = "04/09/2013 15:00:00"; var then = "04/09/2013 14:20:30"; moment.utc(moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss") // outputs: "00:39:30" 

如果你有24小时或更长的时间,上述方法的时间将重置为零,所以它不是理想的。

如果你想获得24小时或更长时间的有效答复,那么你将不得不这样做,而不是:

 var now = "04/09/2013 15:00:00"; var then = "02/09/2013 14:20:30"; var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss")); var d = moment.duration(ms); var s = Math.floor(d.asHours()) + moment.utc(ms).format(":mm:ss"); // outputs: "48:39:30" 

请注意,我正在使用utc时间作为快捷方式。 你可以分别取出d.minutes()d.seconds() ,但是你也必须将它们取消。

这是必要的,因为格式化duration异议的能力目前不在moment.js中。 这里已经要求了 。 但是,有一个叫做时间间隔格式的第三方插件专门用于这个目的:

 var now = "04/09/2013 15:00:00"; var then = "02/09/2013 14:20:30"; var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss")); var d = moment.duration(ms); var s = d.format("hh:mm:ss"); // outputs: "48:39:30" 

您的问题是在格式化之前将moment.duration()的结果传回到moment()中; 这导致了moment()将其解释为相对于Unix纪元的时间。

它并不能完全提供你正在寻找的格式,但是

moment.duration(now.diff(then)).humanize()

会给你一个有用的格式,如“40分钟”。 如果你真的热衷于特定的格式,你必须自己建立一个新的字符串。 一个便宜的方法是

[diff.asHours(), diff.minutes(), diff.seconds()].join(':')

var diff = moment.duration(now.diff(then)) 。 这不会给你单个数字值的零填充。 为此,您可能需要考虑像underscore.string这样的东西 – 虽然看起来还有很长的路要走。 🙂

 var a = moment([2007, 0, 29]); var b = moment([2007, 0, 28]); a.diff(b, 'days') //[days, years, months, seconds, ...] //Result 1 

为我工作

有关详情,请参阅http://momentjs.com/docs/#/displaying/difference/

如果你想两个时间戳的差别只有总天数,小时和分钟,而不是几个月和几年。

 var now = "01/08/2016 15:00:00"; var then = "04/02/2016 14:20:30"; var diff = moment.duration(moment(then).diff(moment(now))); 

差异包含2个月,23天,23小时和20分钟。 但是我们只需要几天,几小时和几分钟的结果,所以简单的解决方案是:

 var days = parseInt(diff.asDays()); //84 var hours = parseInt(diff.asHours()); //2039 hours, but it gives total hours in given miliseconds which is not expacted. hours = hours - days*24; // 23 hours var minutes = parseInt(diff.asMinutes()); //122360 minutes,but it gives total minutes in given miliseconds which is not expacted. minutes = minutes - (days*24*60 + hours*60); //20 minutes. 

最终结果将是:84天23小时20分钟。

当你调用diff ,moment.js计算以毫秒为单位的差值。 如果毫秒传递到duration ,则用于计算正确的持续时间。 然而。 当你将相同的毫秒数传递给moment() ,它将计算从1970年1月1日(午夜UTC / GMT)开始的时间/之后的毫秒数。 这就是为什么你把1969年作为一个错误的时间和一个小时。

 duration.get("hours") +":"+ duration.get("minutes") +":"+ duration.get("seconds") 

所以,我认为这是你应该怎么做,因为moment.js不提供持续时间的format功能。 或者你可以写一个简单的包装,使其更容易/更漂亮。

如果我们只想要hh:mm:ss,我们可以使用这样的函数:

 //param: duration in milliseconds MillisecondsToTime: function(duration) { var seconds = parseInt((duration/1000)%60) , minutes = parseInt((duration/(1000*60))%60) , hours = parseInt((duration/(1000*60*60))%24) , days = parseInt(duration/(1000*60*60*24)); var hoursDays = parseInt(days*24); hours += hoursDays; hours = (hours < 10) ? "0" + hours : hours; minutes = (minutes < 10) ? "0" + minutes : minutes; seconds = (seconds < 10) ? "0" + seconds : seconds; return hours + ":" + minutes + ":" + seconds; } 

代替

 Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss") 

这样做更好

 moment.utc(total.asMilliseconds()).format("HH:mm:ss"); 

这应该工作得很好。

 var now = "04/09/2013 15:00:00"; var then = "02/09/2013 14:20:30"; var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss")); var d = moment.duration(ms); console.log(d.days(), d.hours(), d.minutes(), d.seconds()); 

我用打字机创建一个简单的函数

 const diffDuration: moment.Duration = moment.duration(moment('2017-09-04 12:55').diff(moment('2017-09-02 13:26'))); setDiffTimeString(diffDuration); function setDiffTimeString(diffDuration: moment.Duration) { const str = []; diffDuration.years() > 0 ? str.push(`${diffDuration.years()} year(s)`) : null; diffDuration.months() > 0 ? str.push(`${diffDuration.months()} month(s)`) : null; diffDuration.days() > 0 ? str.push(`${diffDuration.days()} day(s)`) : null; diffDuration.hours() > 0 ? str.push(`${diffDuration.hours()} hour(s)`) : null; diffDuration.minutes() > 0 ? str.push(`${diffDuration.minutes()} minute(s)`) : null; console.log(str.join(', ')); } // output: 1 day(s), 23 hour(s), 29 minute(s) 

用于生成JavaScript https://www.typescriptlang.org/play/index.html

在ES8使用时刻,现在又开始成为时刻对象。

 const duration = moment.duration(now.diff(start)); const timespan = duration.get("hours").toString().padStart(2, '0') +":"+ duration.get("minutes").toString().padStart(2, '0') +":"+ duration.get("seconds").toString().padStart(2, '0');