Hoy vamos a trabajar con JavaScript para calcular la diferencia entre 2 fechas, es decir, calcular el tiempo que ha transcurrido desde una fecha a otra, ya sea para sacar el tiempo transcurrido desde el pasado hasta hoy, desde hoy al futuro o desde una fecha a otra.
Te voy a enseñar a calcular el tiempo transcurrido de manera precisa y también de la manera en la que la calculamos como humanos.
Los ejemplos aquí mostrados podrán ser usados en el lado del cliente o del lado del servidor con Node.
Milisegundos transcurridos entre fechas con JS
Primero vamos a ver cómo obtener la cantidad de milisegundos que han pasado desde una fecha hasta otra. Podemos usar la clase Date
pasando la fecha en el formato AAAA-MM-DDTHH:MM:SS
(en donde la T
es la letra T
literal) para construir el objeto, y luego operar con getTime
:
// En formato AAAA-MM-DDTHH:MM:SS
const milisegundosTranscurridosEntreFechas = (inicio, fin) => {
return new Date(fin).getTime() - new Date(inicio).getTime();
}
Una vez que tenemos los milisegundos podemos obtener cualquier unidad de tiempo haciendo divisiones, es decir, podemos calcular los años, meses, días, horas, minutos y segundos transcurridos.
Tiempo transcurrido preciso
Entonces una vez que tenemos los milisegundos podemos hacer algunas operaciones para calcular el tiempo transcurrido. Primero sacamos los años, luego meses, días, horas, minutos y segundos.
He encerrado este comportamiento en una función de JavaScript que regresa un objeto con todas esas propiedades, así tú puedes usarlos e imprimirlos como prefieras.
const tiempoTranscurridoPreciso = (diferenciaEnMilisegundos) => {
const diasEnUnAño = 365.25;
const diasEnUnMes = 30.437;
const milisegundosEnUnSegundo = 1000;
const milisegundosEnUnMinuto = milisegundosEnUnSegundo * 60;
const milisegundosEnUnaHora = milisegundosEnUnMinuto * 60;
const milisegundosEnUnDia = milisegundosEnUnaHora * 24;
const milisegundosEnUnMes = milisegundosEnUnDia * diasEnUnMes;
const milisegundosEnUnAño = milisegundosEnUnDia * diasEnUnAño;
const años = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnAño);
diferenciaEnMilisegundos -= años * milisegundosEnUnAño;
const meses = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnMes);
diferenciaEnMilisegundos -= meses * milisegundosEnUnMes;
const dias = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnDia);
diferenciaEnMilisegundos -= dias * milisegundosEnUnDia;
const horas = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnaHora);
diferenciaEnMilisegundos -= horas * milisegundosEnUnaHora;
const minutos = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnMinuto);
diferenciaEnMilisegundos -= minutos * milisegundosEnUnMinuto;
const segundos = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnSegundo);
diferenciaEnMilisegundos -= segundos * milisegundosEnUnSegundo;
return { años, meses, dias, horas, minutos, segundos };
}
JavaScript: calcular transcurrido como los humanos lo hacemos
Nosotros calculamos el tiempo de manera distinta.
No tomamos en cuenta años bisiestos ni días del mes, simplemente tomamos el día más cercano del mes y contamos cuántos días han pasado desde ese día, llevando en cuenta los años y meses, además de tomar en cuenta si la fecha ya ha pasado en este año o todavía no.
Tomando eso en cuenta he creado la siguiente función que indica cuánto tiempo ha transcurrido desde una fecha, enfocada a calcular la edad de una persona.
Poniendo todo junto
Ya te he mostrado las 2 funciones, a partir de ellas y usando Date
puedes calcular el tiempo que ha transcurrido entre cualquier período de tiempo ya sea en el navegador o con Node. Veamos un ejemplo de uso:
const inicio = "2020-03-23T21:23:00";
const fin = "2023-09-07T00:00:00";
const diferenciaEnMilisegundos = milisegundosTranscurridosEntreFechas(inicio, fin);
const diferenciaPrecisa = tiempoTranscurridoPreciso(diferenciaEnMilisegundos);
const diferenciaSegunHumanos = tiempoTranscurridoSegunHumanos(inicio);
console.log({ diferenciaEnMilisegundos, diferenciaPrecisa, diferenciaSegunHumanos });
La salida es como se ve a continuación:
Obviamente tú puedes cambiar los formatos y la forma de presentación. El código completo queda así:
// En formato AAAA-MM-DDTHH:MM:SS
const milisegundosTranscurridosEntreFechas = (inicio, fin) => {
return new Date(fin).getTime() - new Date(inicio).getTime();
}
const tiempoTranscurridoPreciso = (diferenciaEnMilisegundos) => {
const diasEnUnAño = 365.25;
const diasEnUnMes = 30.437;
const milisegundosEnUnSegundo = 1000;
const milisegundosEnUnMinuto = milisegundosEnUnSegundo * 60;
const milisegundosEnUnaHora = milisegundosEnUnMinuto * 60;
const milisegundosEnUnDia = milisegundosEnUnaHora * 24;
const milisegundosEnUnMes = milisegundosEnUnDia * diasEnUnMes;
const milisegundosEnUnAño = milisegundosEnUnDia * diasEnUnAño;
const años = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnAño);
diferenciaEnMilisegundos -= años * milisegundosEnUnAño;
const meses = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnMes);
diferenciaEnMilisegundos -= meses * milisegundosEnUnMes;
const dias = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnDia);
diferenciaEnMilisegundos -= dias * milisegundosEnUnDia;
const horas = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnaHora);
diferenciaEnMilisegundos -= horas * milisegundosEnUnaHora;
const minutos = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnMinuto);
diferenciaEnMilisegundos -= minutos * milisegundosEnUnMinuto;
const segundos = Math.floor(diferenciaEnMilisegundos / milisegundosEnUnSegundo);
diferenciaEnMilisegundos -= segundos * milisegundosEnUnSegundo;
return { años, meses, dias, horas, minutos, segundos };
}
const obtenerFechaEnEsteAño = (fechaComoCadena) => {
const ahora = new Date();
const fechaEnEsteAño = new Date(fechaComoCadena);
fechaEnEsteAño.setFullYear(ahora.getFullYear());
return fechaEnEsteAño;
}
const diasEnMesAnterior = () => {
const ahora = new Date();
ahora.setMonth(ahora.getMonth() - 1, 0);
return ahora.getDate();
}
// En formato AAAA-MM-DDTHH:MM:SS
const tiempoTranscurridoSegunHumanos = (fechaComoCadena) => {
let fechaDeNacimiento = new Date(fechaComoCadena);
const ahora = new Date();
const laFechaYaHaPasado = ahora.getTime() > obtenerFechaEnEsteAño(fechaComoCadena).getTime();
let años = ahora.getFullYear() - fechaDeNacimiento.getFullYear() + (laFechaYaHaPasado ? 0 : -1);
let meses, dias;
const diaActual = new Date();
diaActual.setDate(fechaDeNacimiento.getDate());
if (ahora.getDate() < diaActual.getDate()) {
dias = ahora.getDate() + (diasEnMesAnterior() - fechaDeNacimiento.getDate()) + 1;
} else {
dias = ahora.getDate() - fechaDeNacimiento.getDate();
}
if (laFechaYaHaPasado) {
meses = ahora.getMonth() - fechaDeNacimiento.getMonth() - 1;
if (meses < 0) {
meses = 0;
}
} else {
meses = (11 - fechaDeNacimiento.getMonth()) + ahora.getMonth();
}
return { años, meses, dias }
};
const inicio = "2020-03-23T21:23:00";
const fin = "2023-09-07T00:00:00";
const diferenciaEnMilisegundos = milisegundosTranscurridosEntreFechas(inicio, fin);
const diferenciaPrecisa = tiempoTranscurridoPreciso(diferenciaEnMilisegundos);
const diferenciaSegunHumanos = tiempoTranscurridoSegunHumanos(inicio);
console.log({ diferenciaEnMilisegundos, diferenciaPrecisa, diferenciaSegunHumanos });
Te invito a explorar más sobre JavaScript en mi blog.