Ottieni la differenza di tempo tra due giorni

So che posso fare qualsiasi cosa e delle Date più coinvolgenti con i momentjs. Ma imbarazzante, sto attraversando un periodo difficile cercando di fare qualcosa che sembra semplice: ottenere la differenza tra 2 volte.

Esempio:

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

quello che ho provato:

 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 

Non capisco cosa sia quel “10” lì. Vivo in Brasile, quindi siamo utc-0300 se questo è rilevante.

Il risultato di moment.duration(now.diff(then)) è una durata con i valori interni corretti:

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

Quindi, suppongo che la mia domanda sia: come convertire una Duration di momento in un intervallo di tempo? Posso sicuramente usare

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

ma sento che c’è qualcosa di più elegante che mi manca completamente.

aggiornare
guardando più da vicino, nell’esempio sopra now è:

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

e moment(moment.duration(now.diff(then))) è:

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

Non sono sicuro del motivo per cui il secondo valore è in Ora legale (-0200) … ma sono sicuro che non mi piacciono le date 🙁

aggiornamento 2

beh, il valore è -0200 probabilmente perché il 31/12/1969 era una data in cui veniva utilizzata l’ora legale … quindi è così.

Questo approccio funzionerà SOLO quando la durata totale è inferiore a 24 ore:

 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" 

Se hai 24 ore o più, le ore torneranno a zero con l’approccio sopra, quindi non è l’ideale.

Se vuoi ottenere una risposta valida per una durata di 24 ore o superiore, dovrai fare una cosa del genere, invece:

 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" 

Nota che sto usando il tempo di utc come scorciatoia. Potresti estrarre d.minutes() e d.seconds() separatamente, ma dovresti anche zeropadarli.

Questo è necessario perché la possibilità di formattare un’obiezione di duration non è attualmente in moment.js. È stato richiesto qui . Tuttavia, esiste un plug-in di terze parti chiamato formato di durata momento specifico per questo scopo:

 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" 

Il tuo problema è passare il risultato di moment.duration () di nuovo in momento () prima di formattarlo; ciò si traduce in moment () interpretandolo come un tempo relativo all’epoca di Unix.

Non ti dà esattamente il formato che stai cercando, ma

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

ti darebbe un formato utile come “40 minuti”. Se sei davvero appassionato di quella specifica formattazione, dovrai creare una nuova stringa tu stesso. Un modo economico sarebbe

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

dove var diff = moment.duration(now.diff(then)) . Questo non ti dà lo zero padding su valori a cifra singola. Per questo, potresti prendere in considerazione qualcosa come underscore.string – anche se sembra un lungo cammino da fare solo per qualche zeri in più. 🙂

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

Ha funzionato per me

Vedi di più su http://momentjs.com/docs/#/displaying/difference/

Se desideri una differenza di due timestamp in giorni totali, solo ore e minuti, non in mesi e anni.

 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 contiene 2 mesi, 23 giorni, 23 ore e 20 minuti. Ma abbiamo bisogno di risultati solo in giorni, ore e minuti, quindi la soluzione semplice è:

 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. 

Il risultato finale sarà: 84 giorni, 23 ore, 20 minuti.

Quando chiami diff , moment.js calcola la differenza in millisecondi. Se i millisecondi vengono passati alla duration , viene utilizzato per calcolare la durata che è corretta. Però. quando si passa lo stesso millisecondo al moment() , calcola la data che è millisecondi da (dopo) epoca / tempo unix che è il 1 ° gennaio 1970 (mezzanotte UTC / GMT). Questo è il motivo per cui il 1969 è l’anno insieme all’ora sbagliata.

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

Quindi, penso che questo è il modo in cui dovresti farlo poiché moment.js non offre la funzione di format per la durata. Oppure puoi scrivere un semplice wrapper per renderlo più facile / più carino.

Se vogliamo solo hh: mm: ss, possiamo usare una funzione del genere:

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

Questo dovrebbe funzionare bene.

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

Invece di

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

È meglio farlo

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

Creo una semplice funzione con 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) 

per generare javascript https://www.typescriptlang.org/play/index.html

In ES8 usando il momento, ora e inizia ad essere oggetti di momento.

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

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