Uzyskaj różnicę czasu między dwoma czasami danych

246

Wiem, że mogę zrobić wszystko i trochę bardziej zaangażowanych Daty z momentjs. Ale zawstydzające, trudno mi zrobić coś, co wydaje się proste: uzyskać różnicę między 2 razy.

Przykład:

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

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

co próbowałem:

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  

Nie rozumiem, co to tam jest „10”. Mieszkam w Brazylii, więc jesteśmy utc-0300, jeśli to istotne.

Wynikiem moment.duration(now.diff(then))jest czas trwania z prawidłowymi wartościami wewnętrznymi:

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

Wydaje mi się, że moje pytanie brzmi: jak przekonwertować parametr Chwilowość na przedział czasu? Na pewno mogę użyć

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

ale czuję, że jest coś bardziej eleganckiego , czego mi całkowicie brakuje.

aktualizacja
szuka się bliżej, w powyższym przykładzie nowjest:

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

i moment(moment.duration(now.diff(then)))jest:

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

Nie jestem pewien, dlaczego drugą wartością jest czas letni (-0200) ... ale jestem pewien, że nie lubię dat :(

aktualizacja 2

Cóż, wartość wynosi -0200 prawdopodobnie dlatego, że 31.12.1969 była datą, w której użyto czasu dziennego ... więc to tyle.

Lew
źródło
2
„ale jestem pewien, że nie lubię dat”: P Czy czytałeś kiedyś: nodatime.org/unstable/userguide/trivia.html ?
Boris Callens

Odpowiedzi:

367

To podejście zadziała TYLKO, gdy całkowity czas trwania jest krótszy niż 24 godziny:

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"

Jeśli masz 24 godziny lub więcej, godziny zostaną zresetowane do zera przy powyższym podejściu, więc nie jest to idealne.

Jeśli chcesz uzyskać prawidłową odpowiedź na czas 24 godzin lub dłuższy, musisz zamiast tego zrobić coś takiego:

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"

Zauważ, że używam czasu utc jako skrótu. Możesz wyciągnąć d.minutes()i d.seconds()osobno, ale będziesz musiał je też zerować.

Jest to konieczne, ponieważ durationobecnie nie można sformatować sprzeciwu w chwili.js. Poproszono o to tutaj . Istnieje jednak wtyczka innej firmy o nazwie format czasu trwania, która jest specjalnie do tego celu:

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"
Matt Johnson-Pint
źródło
31
@TML - wyraźnie powiedziałem, że nie będzie działać przez 24 godziny lub dłużej.
Matt Johnson-Pint,
1
To działało dobrze. momentjs jest tak elegancką biblioteką, że zaskakuje mnie, że nie ma prostszego sposobu, ale może to, co robię, nie jest tak „normalne”. Prawdopodobnie nie miałbym więcej niż 24 godziny, ale miło jest mieć taką opcję, jeśli tak się stanie. Dzięki za pomoc.
Leo
69

Twój problem polega na tym, że przekazujesz wynik moment.duration () z powrotem do momentu () przed sformatowaniem; powoduje to, że moment () interpretuje go jako czas związany z epoką Uniksa.

Nie daje dokładnie takiego formatu, jakiego szukasz, ale

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

dałby ci przydatny format, np. „40 minut”. Jeśli naprawdę zależy Ci na tym konkretnym formatowaniu, musisz samodzielnie zbudować nowy ciąg. Tani byłby sposób

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

gdzie var diff = moment.duration(now.diff(then)). To nie daje zerowania dla wartości jednocyfrowych. W tym celu możesz rozważyć coś takiego jak podkreślenie. Ciąg - chociaż wydaje się, że jest to długa droga do przejścia tylko o kilka dodatkowych zer. :)

TML
źródło
4
będziesz musiał użyć asHourszamiast hoursi usunąć dziesiętne. W przeciwnym razie miałby to ten sam problem, co problem. :)
Matt Johnson-Pint,
humanize () daje niezły akcent, ale ostatecznie skorzystałem z sugestii Matta. Dzięki za wskazówkę.
Leo
Dzięki za zwrócenie na to uwagi, @MattJohnson - nawet nie zdawałem sobie sprawy z tego, że .Godziny i .godziny były różne, myślałem, że jedno jest po prostu krótszą nazwą dla drugiego, ale przy bliższym przyjrzeniu się masz rację.
TML
2
Uwaga: rozsądnie byłoby użyć: [Math.floor(diff.asHours()), diff.minutes(), diff.seconds()].join(':')w celu uzyskania pożądanego rezultatu. bez dziesiętnego w pierwszej części
KyleM
63
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') //[days, years, months, seconds, ...]
//Result 1 

Pracował dla mnie

Zobacz więcej w http://momentjs.com/docs/#/displaying/difference/

Danilo Colasso
źródło
3
działa to tylko w przypadku dat. OP chciał mieć różnicę czasu
apfz
To najprostsze rozwiązanie, które działa. Tak, także ze znacznikami czasu.
Faheem,
30

Jeśli chcesz różnicę dwóch znaczników czasu w całkowitych dniach, godzinach i minutach, a nie w miesiącach i latach.

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 zawiera 2 miesiące, 23 dni, 23 godziny i 20 minut. Ale potrzebujemy wyniku tylko w dniach, godzinach i minutach, więc proste rozwiązanie to:

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.

Ostateczny wynik to: 84 dni, 23 godziny, 20 minut.

Mahima Agrawal
źródło
19

Kiedy dzwonisz diff, moment.js oblicza różnicę w milisekundach. Jeśli milisekundy są przekazywane duration, służy do obliczania poprawnego czasu trwania. Jednak. kiedy przekażesz te same milisekundy moment(), oblicza datę w milisekundach od (po) epoki / czasu uniksowego, czyli 1 stycznia 1970 r. (północ UTC / GMT). Dlatego otrzymujesz rok 1969 wraz z niewłaściwą godziną.

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

Więc myślę, że tak powinieneś to zrobić, ponieważ moment.js nie oferuje formatfunkcji na czas trwania. Lub możesz napisać proste opakowanie, aby było łatwiejsze / ładniejsze.

Joon
źródło
11

To powinno działać dobrze.

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());
Manzurul
źródło
Lepsze rozwiązanie! :)
JHenry
Najlepsze rozwiązanie w historii
Alaksandar Jesus Gene
9

Jeśli chcemy tylko hh: mm: ss, możemy użyć takiej funkcji:

//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;
}
Filipe Eusébio
źródło
4
Nigdzie w tobie nie widzę użycia momentu. Odpowiedź.
Joel
4

Użyj tego,

  var duration = moment.duration(endDate.diff(startDate));

    var aa = duration.asHours();
Abdus Salam Azad
źródło
3

Zamiast

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

Lepiej to zrobić

moment.utc(total.asMilliseconds()).format("HH:mm:ss");
robinvdvleuten
źródło
2

W ES8 używaj momentu, teraz i zacznij być obiektem momentu.

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');
Fernando Rossato
źródło
2

Maszynopis: następujące powinny działać,

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;
};
skantus
źródło
0

Tworzę prostą funkcję za pomocą maszynopisu

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)

do generowania javascript https://www.typescriptlang.org/play/index.html

Serkan KONAKCI
źródło
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);
    }
Sanket Parchande
źródło
0

WEJŚCIE OPARTE NA CZASIE

    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
    }

WYNIK

{
"status": 200,
"Hour": 0,
"Mins": 5
}
Anandan K.
źródło
0

RÓŻNICA CZASU EPOCH ZA POMOCĄ MOMENTJS :

Aby uzyskać różnicę między dwoma epokami:

Składnia: moment.duration(moment(moment(date1).diff(moment(date2)))).asHours()

Różnica godzin: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asHours()

Różnica w minutach: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asMinutes().toFixed()

Uwaga: Możesz usunąć, .toFixed()jeśli potrzebujesz dokładnych wartości.

Kod:

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

Zapoznaj się z przykładem działania tutaj: https://repl.it/repls/MoccasinDearDimension

aakarsh
źródło