Obtenga la diferencia horaria entre dos fechas


246

Sé que puedo hacer cualquier cosa y algunas fechas más envolventes con momentjs. Pero vergonzosamente, me cuesta mucho intentar 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 probé:

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 somos 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 una duración momentjs en un intervalo de tiempo? Estoy seguro de que puedo usar

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

pero siento que hay algo más elegante que me estoy perdiendo por completo.

actualización
mirando más de cerca, en el ejemplo anterior nowes:

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

y 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 ... así que eso es todo.


2
"pero estoy seguro de que no me gustan las fechas": P ¿Alguna vez leyó esto: nodatime.org/unstable/userguide/trivia.html ?
Boris Callens

Respuestas:


367

Este enfoque funcionará SOLO 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 por una duración de 24 horas o más, deberá hacer algo como esto:

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 retirarse d.minutes()y por d.seconds()separado, pero también tendría que ponerlos a cero.

Esto es necesario porque la capacidad de formatear una durationobjeción no está actualmente en moment.js. Se ha solicitado aquí . Sin embargo, hay un complemento de terceros llamado formato de duración de momento 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"

31
@TML: dije claramente que no funcionaría durante 24 horas o más.
Matt Johnson-Pint

1
Esto funcionó bien. momentjs es una biblioteca tan elegante que me sorprende, no tiene una forma más simple, pero tal vez lo que estoy haciendo no es tan "normal". Probablemente no tendría más de 24 horas, pero es bueno tener la opción si sucede. Gracias por tu ayuda.
Leo

69

Su problema es pasar el resultado de moment.duration () a moment () antes de formatearlo; esto da como resultado moment () interpretándolo 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()

le daría un formato útil como "40 minutos". Si realmente está interesado en ese formato específico, tendrá que construir 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 de cero en valores de un solo dígito. Para eso, es posible que desee considerar algo como el subrayado.cadena , aunque parece un largo camino por recorrer solo para unos pocos ceros adicionales. :)


44
tendrá que usar en asHourslugar de hoursy quitar los decimales. De lo contrario, tendría el mismo problema que captó en mi respuesta. :)
Matt Johnson-Pint

humanize () le da un toque agradable pero terminé usando la sugerencia de Matt. Gracias por el consejo.
Leo

Gracias por señalar eso, @MattJohnson: ni siquiera me había dado cuenta de que las horas y las horas eran diferentes, pensé que uno era solo un nombre más corto para el otro, pero en una inspección más cercana, tienes razón.
TML

2
Tenga en cuenta que sería aconsejable usar: [Math.floor(diff.asHours()), diff.minutes(), diff.seconds()].join(':')para obtener el resultado deseado. sin un decimal en la primera parte
KyleM


30

Si desea una diferencia de dos marcas de tiempo en el total de días, horas y minutos solamente, 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)));

diff 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.


19

Cuando llama diff, moment.js calcula la diferencia en milisegundos. Si se pasan los milisegundos duration, se usa para calcular la duración correcta. Sin embargo. cuando pasa los mismos milisegundos al moment(), calcula la fecha en milisegundos desde (después) el tiempo 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 debería hacerlo, ya que moment.js no ofrece la formatfunción por la duración. O puede escribir un contenedor simple para hacerlo más fácil / más bonito.


11

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

¡Mejor solución! :)
JHenry

La mejor solución
Alaksandar Jesus Gene

9

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

44
No veo el momento de uso en ninguna parte de su respuesta.
Joel

4

Utilizar este,

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

    var aa = duration.asHours();

3

En vez de

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

Es mejor hacerlo

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

2

En ES8 usa momento, ahora y comienza a ser objeto 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');

2

Mecanografiado: lo siguiente debería funcionar,

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

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


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

FECHA HORA ENTRADA BASADA

    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
    }

SALIDA

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

0

DIFERENCIA DE TIEMPO DE ÉPOCA CON MOMENTJS :

Para obtener la diferencia entre dos tiempos de época:

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

Diferencia en horas: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asHours()

Diferencia en minutos: moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asMinutes().toFixed()

Nota: Puede eliminar .toFixed()si necesita valores precisos.

Código:

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

Consulte el ejemplo de trabajo aquí: https://repl.it/repls/MoccasinDearDimension

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.