获取两个日期之间的时差

时间:2021-12-21 00:26:24

I know I can do anything and some more envolving Dates with momentjs. But embarrassingly, I'm having a hard time trying to do something that seems simple: geting the difference between 2 times.

我知道我可以做任何事,也可以和momentjs一起参加更多的约会。但令人尴尬的是,我很难做一些看似简单的事情:计算两次的差值。

Example:

例子:

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

//expected result:
"00:39:30"

what I tried:

我试着什么:

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  

I do not understand what is that "10" there. I live in Brazil, so we are utc-0300 if that is relevant.

我不明白那“10”是什么意思。我住在巴西,如果相关的话,我们是utc-0300。

The result of moment.duration(now.diff(then)) is a duration with the correct internal values:

持续时间(now.diff(then))的结果是具有正确内部值的持续时间:

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

So, I guess my question is: how to convert a momentjs Duration to a time interval? I sure can use

我想我的问题是:如何将动量持续时间转换成时间间隔?我确定可以使用

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

but i feel that there is something more elegant that I am completely missing.

但我觉得有一种更优雅的东西是我完全没有的。

update
looking closer, in the above example now is:

更新查看更近,在上面的例子现在是:

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

and moment(moment.duration(now.diff(then))) is:

和时刻(moment.duration(now.diff(然后)))是:

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

I am not sure why the second value is in Daylight Time (-0200)... but I am sure that i do not like dates :(

我不知道为什么第二个值在日光时间(-0200)…但是我确定我不喜欢约会

update 2

更新2

well, the value is -0200 probably because 31/12/1969 was a date where the daylight time was being used... so thats that.

它的值是-0200可能是因为31/12/1969是使用日光时间的日期…所以这。

10 个解决方案

#1


275  

This approach will work ONLY when the total duration is less than 24 hours:

这种方法只有在总持续时间少于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"

If you have 24 hours or more, the hours will reset to zero with the above approach, so it is not ideal.

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

If you want to get a valid response for durations of 24 hours or greater, then you'll have to do something like this instead:

如果你想在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"

Note that I'm using the utc time as a shortcut. You could pull out d.minutes() and d.seconds() separately, but you would also have to zeropad them.

注意,我使用utc时间作为快捷方式。你可以把d.minutes()和d.seconds()分开,但是你也要把它们调零。

This is necessary because the ability to format a duration objection is not currently in moment.js. It has been requested here. However, there is a third-party plugin called moment-duration-format that is specifically for this purpose:

这是必要的,因为目前还没有设置持续时间异议的能力。这是我们要求的。但是,有一个第三方插件叫做“时间-持续-格式”,专门用于这个目的:

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"

#2


51  

Your problem is in passing the result of moment.duration() back into moment() before formatting it; this results in moment() interpreting it as a time relative to the Unix epoch.

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

It doesn't give you exactly the format you're looking for, but

它并没有给出你想要的格式,但是。

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

moment.duration(now.diff(当时).humanize()

would give you a useful format like "40 minutes". If you're really keen on that specific formatting, you'll have to build a new string yourself. A cheap way would be

会给你一个有用的格式,比如“40分钟”。如果您非常喜欢特定的格式,那么您必须自己构建一个新的字符串。一种廉价的方式。

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

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

where var diff = moment.duration(now.diff(then)). This doesn't give you the zero-padding on single digit values. For that, you might want to consider something like underscore.string - although it seems like a long way to go just for a few extra zeroes. :)

其中var diff =力矩。持续时间(现在)。这不会给你一个数字上的零填充。为此,您可能需要考虑下划线之类的东西。字符串——尽管仅仅为了几个额外的0看起来是很长的一段路。:)

#3


46  

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

Worked for me

为我工作

See more in http://momentjs.com/docs/#/displaying/difference/

看到更多的在http://momentjs.com/docs/ / /显示/不同

#4


21  

If you want difference of two timestamp into total days,hours and minutes only, not in months and years .

如果你想把两个时间戳的差值转换成天、小时和分钟,而不是月和年。

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

diff contains 2 months,23 days,23 hours and 20 minutes. But we need result only in days,hours and minutes so the simple solution is:

diff包括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.

Final result will be : 84 days, 23 hours, 20 minutes.

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

#5


18  

When you call diff, moment.js calculates the difference in milliseconds. If the milliseconds is passed to duration, it is used to calculate duration which is correct. However. when you pass the same milliseconds to the moment(), it calculates the date that is milliseconds from(after) epoch/unix time that is January 1, 1970 (midnight UTC/GMT). That is why you get 1969 as the year together with wrong hour.

当你呼唤迪夫的时候。js计算毫秒差。如果将毫秒传递给持续时间,则用于计算正确的持续时间。然而。当您将相同的毫秒传递到moment()时,它计算的日期是在1970年1月1日(UTC/GMT)之后的(后)纪元/unix时间。这就是为什么1969年是你和错误的时间在一起的一年。

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

So, I think this is how you should do it since moment.js does not offer format function for duration. Or you can write a simple wrapper to make it easier/prettier.

所以,我认为这就是你现在应该做的。js不提供格式功能。或者你可以写一个简单的包装使它更容易/更漂亮。

#6


7  

If we want only hh:mm:ss, we can use a function like that:

如果我们只需要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;
}

#7


5  

This should work fine.

这应该工作很好。

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());

#8


3  

Instead of

而不是

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

It's better to do

做得好

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

#9


0  

I create a simple function with typescript

我用typescript创建了一个简单的函数

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)

for generate javascript https://www.typescriptlang.org/play/index.html

对生成的javascript的https://www.typescriptlang.org/play/index.html

#10


0  

In ES8 using moment, now and start being moment objects.

在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');

#1


275  

This approach will work ONLY when the total duration is less than 24 hours:

这种方法只有在总持续时间少于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"

If you have 24 hours or more, the hours will reset to zero with the above approach, so it is not ideal.

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

If you want to get a valid response for durations of 24 hours or greater, then you'll have to do something like this instead:

如果你想在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"

Note that I'm using the utc time as a shortcut. You could pull out d.minutes() and d.seconds() separately, but you would also have to zeropad them.

注意,我使用utc时间作为快捷方式。你可以把d.minutes()和d.seconds()分开,但是你也要把它们调零。

This is necessary because the ability to format a duration objection is not currently in moment.js. It has been requested here. However, there is a third-party plugin called moment-duration-format that is specifically for this purpose:

这是必要的,因为目前还没有设置持续时间异议的能力。这是我们要求的。但是,有一个第三方插件叫做“时间-持续-格式”,专门用于这个目的:

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"

#2


51  

Your problem is in passing the result of moment.duration() back into moment() before formatting it; this results in moment() interpreting it as a time relative to the Unix epoch.

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

It doesn't give you exactly the format you're looking for, but

它并没有给出你想要的格式,但是。

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

moment.duration(now.diff(当时).humanize()

would give you a useful format like "40 minutes". If you're really keen on that specific formatting, you'll have to build a new string yourself. A cheap way would be

会给你一个有用的格式,比如“40分钟”。如果您非常喜欢特定的格式,那么您必须自己构建一个新的字符串。一种廉价的方式。

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

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

where var diff = moment.duration(now.diff(then)). This doesn't give you the zero-padding on single digit values. For that, you might want to consider something like underscore.string - although it seems like a long way to go just for a few extra zeroes. :)

其中var diff =力矩。持续时间(现在)。这不会给你一个数字上的零填充。为此,您可能需要考虑下划线之类的东西。字符串——尽管仅仅为了几个额外的0看起来是很长的一段路。:)

#3


46  

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

Worked for me

为我工作

See more in http://momentjs.com/docs/#/displaying/difference/

看到更多的在http://momentjs.com/docs/ / /显示/不同

#4


21  

If you want difference of two timestamp into total days,hours and minutes only, not in months and years .

如果你想把两个时间戳的差值转换成天、小时和分钟,而不是月和年。

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

diff contains 2 months,23 days,23 hours and 20 minutes. But we need result only in days,hours and minutes so the simple solution is:

diff包括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.

Final result will be : 84 days, 23 hours, 20 minutes.

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

#5


18  

When you call diff, moment.js calculates the difference in milliseconds. If the milliseconds is passed to duration, it is used to calculate duration which is correct. However. when you pass the same milliseconds to the moment(), it calculates the date that is milliseconds from(after) epoch/unix time that is January 1, 1970 (midnight UTC/GMT). That is why you get 1969 as the year together with wrong hour.

当你呼唤迪夫的时候。js计算毫秒差。如果将毫秒传递给持续时间,则用于计算正确的持续时间。然而。当您将相同的毫秒传递到moment()时,它计算的日期是在1970年1月1日(UTC/GMT)之后的(后)纪元/unix时间。这就是为什么1969年是你和错误的时间在一起的一年。

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

So, I think this is how you should do it since moment.js does not offer format function for duration. Or you can write a simple wrapper to make it easier/prettier.

所以,我认为这就是你现在应该做的。js不提供格式功能。或者你可以写一个简单的包装使它更容易/更漂亮。

#6


7  

If we want only hh:mm:ss, we can use a function like that:

如果我们只需要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;
}

#7


5  

This should work fine.

这应该工作很好。

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());

#8


3  

Instead of

而不是

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

It's better to do

做得好

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

#9


0  

I create a simple function with typescript

我用typescript创建了一个简单的函数

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)

for generate javascript https://www.typescriptlang.org/play/index.html

对生成的javascript的https://www.typescriptlang.org/play/index.html

#10


0  

In ES8 using moment, now and start being moment objects.

在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');