Ermitteln Sie den Zeitunterschied zwischen zwei Datumsangaben

246

Ich weiß, dass ich mit momentjs alles und noch mehr Termine machen kann. Aber peinlich, es fällt mir schwer, etwas zu tun, das einfach zu sein scheint: den Unterschied zwischen zwei Mal zu bekommen.

Beispiel:

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

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

was ich versucht habe:

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  

Ich verstehe nicht, was diese "10" dort ist. Ich lebe in Brasilien, also sind wir utc-0300, wenn das relevant ist.

Das Ergebnis moment.duration(now.diff(then))ist eine Dauer mit den richtigen internen Werten:

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

Ich denke also, meine Frage ist: Wie konvertiere ich die Dauer eines Moments in ein Zeitintervall? Ich kann sicher verwenden

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

aber ich fühle, dass es etwas eleganteres gibt , das mir völlig fehlt.

Das Update
, das genauer betrachtet wird, ist im obigen Beispiel now:

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

und moment(moment.duration(now.diff(then)))ist:

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

Ich bin nicht sicher, warum der zweite Wert in der Sommerzeit (-0200) ist ... aber ich bin sicher, dass ich keine Daten mag :(

Update 2

Nun, der Wert ist -0200, wahrscheinlich weil der 31.12.1969 ein Datum war, an dem die Sommerzeit verwendet wurde ... also das ist es.

Löwe
quelle
2
"aber ich bin sicher, dass ich keine Daten mag": P Hast du das jemals gelesen: nodatime.org/unstable/userguide/trivia.html ?
Boris Callens

Antworten:

366

Dieser Ansatz funktioniert NUR, wenn die Gesamtdauer weniger als 24 Stunden beträgt:

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"

Wenn Sie 24 Stunden oder mehr Zeit haben, werden die Stunden mit dem oben beschriebenen Ansatz auf Null zurückgesetzt, sodass dies nicht ideal ist.

Wenn Sie eine gültige Antwort für eine Dauer von 24 Stunden oder mehr erhalten möchten, müssen Sie stattdessen Folgendes tun:

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"

Beachten Sie, dass ich die utc-Zeit als Verknüpfung verwende. Sie könnten herausziehen d.minutes()und d.seconds()separat, aber Sie müssten sie auch auf Null setzen.

Dies ist erforderlich, da die Möglichkeit zum Formatieren eines durationEinspruchs derzeit nicht in moment.js vorhanden ist. Es wurde hier angefordert . Es gibt jedoch ein Plugin eines Drittanbieters namens Moment-Duration-Format , das speziell für diesen Zweck entwickelt wurde:

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
quelle
31
@TML - Ich habe klar gesagt, dass es für eine Dauer von 24 Stunden oder länger nicht funktionieren würde.
Matt Johnson-Pint
1
Das hat gut funktioniert. momentjs ist eine so elegante Bibliothek, dass es mich überrascht, dass es keinen einfacheren Weg gibt, aber vielleicht ist das, was ich tue, nicht so "normal". Ich hätte wahrscheinlich nicht mehr als 24 Stunden Zeit, aber es ist schön, die Option zu haben, wenn es passiert. Danke für Ihre Hilfe.
Leo
69

Ihr Problem besteht darin, das Ergebnis von moment.duration () vor dem Formatieren wieder in moment () zu übertragen. Dies führt dazu, dass moment () es als eine Zeit relativ zur Unix-Epoche interpretiert.

Es gibt Ihnen nicht genau das Format, das Sie suchen, aber

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

würde Ihnen ein nützliches Format wie "40 Minuten" geben. Wenn Sie sich wirklich für diese spezielle Formatierung interessieren, müssen Sie selbst eine neue Zeichenfolge erstellen. Ein billiger Weg wäre

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

wo var diff = moment.duration(now.diff(then)). Dies gibt Ihnen keine Null-Auffüllung für einstellige Werte. Dafür möchten Sie vielleicht etwas wie underscore.string in Betracht ziehen - obwohl es ein langer Weg zu sein scheint, nur ein paar zusätzliche Nullen zu machen. :) :)

TML
quelle
4
Sie müssen asHoursstattdessen verwenden hoursund die Dezimalstellen abziehen. Andernfalls hätte es das gleiche Problem, das Sie in meiner Antwort festgestellt haben. :)
Matt Johnson-Pint
humanize () gibt eine nette Geste, aber am Ende habe ich Matt Vorschlag verwendet. Danke für den Tipp.
Leo
Vielen Dank für den Hinweis, @MattJohnson - ich hatte nicht einmal bemerkt, dass .asHours und .hours unterschiedlich waren, dachte, einer sei nur ein kürzerer Name für den anderen, aber bei näherer Betrachtung haben Sie Recht.
TML
2
Beachten Sie, dass es ratsam ist, Folgendes zu verwenden [Math.floor(diff.asHours()), diff.minutes(), diff.seconds()].join(':'), um das gewünschte Ergebnis zu erzielen. ohne Dezimalstelle im ersten Teil
KyleM
30

Wenn Sie eine Differenz von zwei Zeitstempeln in Tage, Stunden und Minuten wünschen, nicht in Monaten und Jahren.

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 enthält 2 Monate, 23 Tage, 23 Stunden und 20 Minuten. Das Ergebnis muss jedoch nur in Tagen, Stunden und Minuten angegeben werden. Die einfache Lösung lautet also:

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.

Das Endergebnis ist: 84 Tage, 23 Stunden, 20 Minuten.

Mahima Agrawal
quelle
19

Beim Aufruf diffberechnet moment.js die Differenz in Millisekunden. Wenn die Millisekunden an übergeben werden, durationwird sie verwendet, um die korrekte Dauer zu berechnen. Jedoch. Wenn Sie die gleichen Millisekunden an die übergeben moment(), wird das Datum berechnet, das Millisekunden von (nach) der Epoche / Unix-Zeit am 1. Januar 1970 (Mitternacht UTC / GMT) entfernt ist. Deshalb bekommen Sie 1969 als das Jahr zusammen mit der falschen Stunde.

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

Ich denke, so sollten Sie es machen, da moment.js keine formatFunktion für die Dauer bietet . Oder Sie können einen einfachen Wrapper schreiben, um ihn einfacher / schöner zu machen.

Joon
quelle
11

Dies sollte gut funktionieren.

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
quelle
Bessere Lösung! :)
JHenry
Beste Lösung aller Zeiten
Alaksandar Jesus Gene
9

Wenn wir nur hh: mm: ss wollen, können wir eine Funktion wie diese verwenden:

//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
quelle
4
Ich sehe keinen Moment in deiner Antwort.
Joel
4

Benutze das,

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

    var aa = duration.asHours();
Abdus Salam Azad
quelle
3

Anstatt

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

Es ist besser zu tun

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

Verwenden Sie in ES8 jetzt Moment und beginnen Sie, Momentobjekte zu sein.

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
quelle
2

Typoskript: Folgendes sollte funktionieren,

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
quelle
0

Ich erstelle eine einfache Funktion mit Typoskript

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)

zum Generieren von Javascript https://www.typescriptlang.org/play/index.html

Serkan KONAKCI
quelle
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
quelle
0

DATUM ZEITBASIERTER EINGANG

    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
    }

AUSGABE

{
"status": 200,
"Hour": 0,
"Mins": 5
}
Anandan K.
quelle
0

EPOCH-ZEITUNTERSCHIED MIT MOMENTJS :

So erhalten Sie einen Unterschied zwischen zwei Epochen:

Syntax: moment.duration(moment(moment(date1).diff(moment(date2)))).asHours()

Stundenunterschied: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asHours()

Unterschied in Minuten: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asMinutes().toFixed()

Hinweis: Sie können entfernen.toFixed() wenn Sie genaue Werte benötigen.

Code:

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

Siehe Arbeitsbeispiel hier: https://repl.it/repls/MoccasinDearDimension

aakarsh
quelle