javascript - restar - Obtener la diferencia de tiempo entre dos fechas
restar horas con moment js (11)
Creo una función simple con mecanografiado.
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)
para generar javascript https://www.typescriptlang.org/play/index.html
Sé que puedo hacer cualquier cosa y algunas fechas más envolventes con momentjs. Pero vergonzosamente, me cuesta trabajo hacer algo que parece simple: obtener la diferencia entre 2 veces.
Ejemplo:
var now = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";
//expected result:
"00:39:30"
lo que intenté
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
No entiendo qué es ese "10" allí. Vivo en Brasil, así que estamos utc-0300 si eso es relevante.
El resultado de moment.duration(now.diff(then))
es una duración con los valores internos correctos:
days: 0
hours: 0
milliseconds: 0
minutes: 39
months: 0
seconds: 30
years: 0
Entonces, supongo que mi pregunta es: ¿cómo convertir la duración de un momento en un intervalo de tiempo? Seguro que puedo usar
duration.get("hours") +":"+ duration.get("minutes") +:+ duration.get("seconds")
Pero siento que hay algo más elegante que me falta por completo.
actualizar
Mirando más de cerca, en el ejemplo anterior now
está:
Tue Apr 09 2013 15:00:00 GMT-0300 (E. South America Standard Time)…}
y el moment(moment.duration(now.diff(then)))
es:
Wed Dec 31 1969 22:39:30 GMT-0200 (E. South America Daylight Time)…}
No estoy seguro de por qué el segundo valor está en el horario de verano (-0200) ... pero estoy seguro de que no me gustan las fechas :(
actualización 2
Bueno, el valor es -0200 probablemente porque el 31/12/1969 era una fecha en la que se usaba el horario de verano ... y eso es todo.
Cuando llama a diff
, moment.js calcula la diferencia en milisegundos. Si los milisegundos se pasan a la duration
, se utiliza para calcular la duración que es correcta. Sin embargo. cuando pasa los mismos milisegundos hasta el moment()
, calcula la fecha en milisegundos desde (después) de la época de época / unix que es el 1 de enero de 1970 (medianoche UTC / GMT). Es por eso que obtienes 1969 como el año junto con la hora equivocada.
duration.get("hours") +":"+ duration.get("minutes") +":"+ duration.get("seconds")
Entonces, creo que así es como debes hacerlo ya que moment.js no ofrece una función de format
para la duración. O puede escribir un envoltorio simple para hacerlo más fácil / más bonito.
En ES8 usa moment, ahora y empieza a ser objetos de 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'');
En lugar de
Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss")
Es mejor hacer
moment.utc(total.asMilliseconds()).format("HH:mm:ss");
Esto debería funcionar bien.
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());
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);
}
Si desea la diferencia de dos marcas de tiempo en el total de días, horas y minutos, no en meses y años.
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)));
Dif contiene 2 meses, 23 días, 23 horas y 20 minutos. Pero necesitamos resultados solo en días, horas y minutos, por lo que la solución simple es:
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.
El resultado final será: 84 días, 23 horas, 20 minutos.
Si solo queremos hh: mm: ss, podemos usar una función como esa:
//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;
}
Su problema es pasar el resultado de moment.duration () de nuevo a moment () antes de formatearlo; esto resulta en el momento () de interpretarlo como un tiempo relativo a la época de Unix.
No te da exactamente el formato que estás buscando, pero
moment.duration(now.diff(then)).humanize()
Te daría un formato útil como "40 minutos". Si está realmente interesado en ese formato específico, tendrá que crear una nueva cadena usted mismo. Una forma barata sería
[diff.asHours(), diff.minutes(), diff.seconds()].join('':'')
donde var diff = moment.duration(now.diff(then))
. Esto no le da el relleno cero en valores de un solo dígito. Para eso, es posible que desee considerar algo como underscore.string - aunque parece un largo camino por recorrer solo por unos pocos ceros adicionales. :)
Este enfoque funcionará SOLAMENTE cuando la duración total sea inferior a 24 horas:
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"
Si tiene 24 horas o más, las horas se restablecerán a cero con el enfoque anterior, por lo que no es lo ideal.
Si desea obtener una respuesta válida para duraciones de 24 horas o más, tendrá que hacer algo como esto en su lugar:
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"
Tenga en cuenta que estoy usando el tiempo utc como acceso directo. Podría sacar d.minutes()
y d.seconds()
separado, pero también tendría que zeropad ellos.
Esto es necesario porque la capacidad de formatear una objeción de duration
no se encuentra actualmente en moment.js. Se ha solicitado aquí . Sin embargo, hay un complemento de terceros llamado moment-duration-format que es específicamente para este propósito:
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"
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, ''days'') //[days, years, months, seconds, ...]
//Result 1
Trabajó para mi
Ver más en http://momentjs.com/docs/#/displaying/difference/