2013-09-04 6 views
173

Я знаю, что я могу сделать что угодно и еще что-нибудь, предлагаю Даты с импульсами. Но смущающе, я с трудом пытаюсь сделать что-то, что кажется простым: получить разницу между 2 раза.Получите разницу во времени между двумя днями времени

Пример:

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 было датой, когда использовалось дневное время ... так вот что.

+0

«но я уверен, что я не люблю даты»: P Вы когда-нибудь прочитать: http://nodatime.org/unstable/userguide/trivia.html? –

ответ

266

Этот подход будет работать только тогда, когда общая продолжительность составляет менее 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() отдельно, но вам также нужно было бы их заменить.

Это необходимо, потому что возможность отформатировать возражение в настоящий момент отсутствует. Js. It has been requested here. Тем не менее, есть сторонний плагин под названием moment-duration-format, который специально для этой цели:

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" 
+0

'var now =" 04/09/2013 15:00:00 "; var then = "02/09/2013 14:20:30"; moment.utc (момент (сейчас, «DD/MM/YYYY HH: mm: ss»). Diff (момент (затем «DD/MM/YYYY HH: mm: ss»))). Format («HH: мм: ss ")' дает '00: 39: 30'. Это явно неправильно. – TML

+22

@TML - Я ясно сказал, что он не будет работать в течение 24 часов или дольше. –

+0

Это сработало отлично. momentjs - такая элегантная библиотека, она удивляет меня, что у нее нет более простого способа, но, возможно, то, что я делаю, не так «нормально». У меня, вероятно, не было бы более 24 часов, но приятно иметь вариант, если это произойдет. Спасибо за вашу помощь. – Leo

17

Когда вы вызываете diff, момент.js вычисляет разницу в миллисекундах. Если миллисекунды переданы на номер duration, то используется для вычисления правильной длительности. Однако. когда вы передаете те же миллисекунды на moment(), он вычисляет дату, которая составляет миллисекунду от (после) эпохи/времени unix, которая составляет 1 января 1970 года (полуночный UTC/GMT). Вот почему вы получаете 1969 год как год вместе с неправильным часом.

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

Так что, я думаю, что это, как вы должны делать это, так как moment.js не предлагает format функцию продолжительности. Или вы можете написать простую обертку, чтобы сделать ее проще/красивее.

45

Ваша проблема заключается в передаче результата момента.duration() назад в момент() перед форматированием; это приводит к тому, что момент() интерпретирует его как время относительно эпохи Unix.

Это не дает вам именно формат, который вы ищете, но

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

даст вам полезный формат, как «40 минут». Если вы действительно заинтересованы в этом конкретном форматировании, вам придется самостоятельно создавать новую строку. Дешевый способ будет

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

где var diff = moment.duration(now.diff(then)). Это не дает вам нулевое дополнение для значений с одной цифрой. Для этого вы можете рассмотреть что-то вроде underscore.string - хотя кажется, что это долгий путь для нескольких лишних нулей. :)

+4

вам нужно будет использовать 'asHours' вместо' hours' и снять десятичные знаки. В противном случае у вас будет та же проблема, что и в моем ответе. :) –

+0

humanize() дает приятное прикосновение, но я в конечном итоге использовал предложение Мэтта. Спасибо за совет. – Leo

+0

Спасибо, что указали, что @MattJohnson - я даже не осознал. Часы и часы были разными, считая, что это было более короткое имя для другого, но при ближайшем рассмотрении вы правы. – TML

3

Вместо

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

Это лучше сделать

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

Не рекомендуется, так как HH будет сбрасываться каждые 24 часа. –

7

Если мы хотим только чч : 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; 
} 
+3

Я не вижу возможности использования в любом месте в вашем ответе. – Joel

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

+1

Это работает только для дат. OP хотел иметь разницу во времени – apfz

20

Если вы хотите разницу два метки времени в полные дни, часы и минуты только, а не в месяцах и лет.

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 содержит 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 минут.

4

Это должно работать нормально.

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

Я создаю простую функцию с машинописью

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

0

В 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'); 
Смежные вопросы