Получите разницу во времени между двумя датами


246

Я знаю, что могу сделать что-нибудь еще и еще более привлекательные Даты с моментами. Но смущающе, я с трудом пытаюсь сделать что-то, что кажется простым: получить разницу между 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

Итак, я думаю, мой вопрос: как преобразовать продолжительность момента в временной интервал? Я уверен, что могу использовать

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


2
«но я уверен, что мне не нравятся даты»: P Вы когда-нибудь читали это: nodatime.org/unstable/userguide/trivia.html ?
Борис Калленс

Ответы:


367

Этот подход будет работать ТОЛЬКО в том случае, если общая продолжительность составляет менее 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"

31
@TML - я ясно сказал, что это не будет работать в течение 24 часов или дольше.
Мэтт Джонсон-Пинт

1
Это работало нормально. momentjs - это такая элегантная библиотека, что удивляет меня, что у нее нет более простого способа, но, возможно, то, что я делаю, не так "нормально". У меня, вероятно, не было бы больше 24 часов, но было бы неплохо, если бы это случилось. Спасибо за вашу помощь.
Лев

70

Ваша проблема заключается в передаче результата 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 - хотя кажется, что это долгий путь только для нескольких дополнительных нулей. :)


4
вам придется использовать asHoursвместо hours, и снять десятичные дроби. В противном случае это будет та же проблема, что вы поймали в моем ответе. :)
Мэтт Джонсон-Пинт

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

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

2
Обратите внимание, было бы целесообразно использовать: [Math.floor(diff.asHours()), diff.minutes(), diff.seconds()].join(':')для того, чтобы получить желаемый результат. без десятичной дроби в первой части
KyleM

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


3
это работает только для дат. ОП хотел иметь разницу во времени
apfz

Это самое простое решение, которое работает. Да, с отметками времени тоже.
Фахим

30

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

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 минут.


19

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

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

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


11

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

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

Лучшее решение! :)
Дженри

Лучшее решение за всю историю
Александр Иисус Джин

9

Если мы хотим только чч: мм: сс, мы можем использовать такую ​​функцию:

//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;
}

4
Я не вижу нигде в вашем ответе использования моментов.
Джоэл


3

Вместо того

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

Лучше сделать

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

2

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

2

Машинопись: следующее должно работать,

export const getTimeBetweenDates = ({
  until,
  format
}: {
  until: number;
  format: 'seconds' | 'minutes' | 'hours' | 'days';
}): number => {
  const date = new Date();
  const remainingTime = new Date(until * 1000);
  const getFrom = moment([date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()]);
  const getUntil = moment([remainingTime.getUTCFullYear(), remainingTime.getUTCMonth(), remainingTime.getUTCDate()]);
  const diff = getUntil.diff(getFrom, format);
  return !isNaN(diff) ? diff : null;
};

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

InTime = 06: 38, Outtime = 15: 40

 calTimeDifference(){
        this.start = dailyattendance.InTime.split(":");
        this.end = dailyattendance.OutTime.split(":");
        var time1 = ((parseInt(this.start[0]) * 60) + parseInt(this.start[1]))
        var time2 = ((parseInt(this.end[0]) * 60) + parseInt(this.end[1]));
        var time3 = ((time2 - time1) / 60);
        var timeHr = parseInt(""+time3);
        var  timeMin = ((time2 - time1) % 60);
    }

0

ДАТА ВРЕМЯ НА ОСНОВЕ ВХОДА

    var dt1 = new Date("2019-1-8 11:19:16");
    var dt2 = new Date("2019-1-8 11:24:16");


    var diff =(dt2.getTime() - dt1.getTime()) ;
    var hours = Math.floor(diff / (1000 * 60 * 60));
    diff -= hours * (1000 * 60 * 60);
    var mins = Math.floor(diff / (1000 * 60));
    diff -= mins * (1000 * 60);


    var response = {
        status : 200,
        Hour : hours,
        Mins : mins
    }

ВЫВОД

{
"status": 200,
"Hour": 0,
"Mins": 5
}

0

Эпоха разницы во времени с использованием моментов :

Чтобы получить разницу между двумя эпохами:

Синтаксис: moment.duration(moment(moment(date1).diff(moment(date2)))).asHours()

Разница в часах: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asHours()

Разница в минутах: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asMinutes().toFixed()

Примечание: вы можете удалить.toFixed() если вам нужны точные значения.

Код:

const moment = require('moment')

console.log('Date 1',moment(1590597909877).toISOString())
console.log('Date 2',moment(1590597744551).toISOString())
console.log('Date1 - Date 2 time diffrence is : ',moment.duration(moment(moment(1590597909877).diff(moment(1590597744551)))).asMinutes().toFixed()+' minutes')

См. Рабочий пример здесь: https://repl.it/repls/MoccasinDearDimension

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.