Al usar JavaScript con la clase Date podemos calcular el tiempo exacto transcurrido entre 2 fechas, pero los humanos (o al menos yo) calculamos las edades de manera distinta.
Cuando calculamos la edad de una persona necesitamos saber el día de nacimiento y su cumpleaños en el año actual. También revisamos si ya ha cumplido años en este año o todavía no (para hacer la diferencia de años), contamos los meses completos y los días transcurridos desde el mes completo más cercano.
Por ello es que el algoritmo es totalmente distinto, ya que no solo se trata de obtener el tiempo exacto, sino de hacerlo como lo hacemos mentalmente. Justamente de eso trata el ejercicio de hoy.
Comencemos revisando unas funciones que nos van a decir cuántos días tiene un mes, ya sea el mes actual o el mes anterior.
Aquí aprovecho para decirte que todas las funciones requieren un objeto Date
con la fecha actual para hacer los cálculos relativos a ella. De este modo se pueden hacer pruebas con varias fechas, simulando que la fecha actual es otra.
const diasEnElMesAnterior = (fecha) => {
const clon = new Date(fecha.getTime());
clon.setMonth(clon.getMonth(), 0);
return clon.getDate();
}
const diasEnElMes = (fecha) => {
const clon = new Date(fecha.getTime());
clon.setMonth(clon.getMonth() + 1, 0);
return clon.getDate();
}
La siguiente función te dice cuándo cumple años la persona en el año actual:
const obtenerCumpleañosDeEsteAño = (fechaDeNacimientoComoCadena, fecha) => {
const cumpleañosEsteAño = new Date(fechaDeNacimientoComoCadena);
cumpleañosEsteAño.setFullYear(fecha.getFullYear());
return cumpleañosEsteAño;
}
Lo siguiente para calcular la edad de una persona con JS es computar los años, meses y días transcurridos. Todo esto cambia dependiendo de la fecha actual y de si el cumpleaños ha pasado o no.
Para calcular los años solamente calculamos la diferencia entre el año actual y el de nacimiento, pero en caso de que todavía no tenga “los años cumplidos” en la fecha actual, restamos uno.
Es la función más simple:
const obtenerAños = (nacimiento, ahora, cumpleañosEsteAño) => {
let años = ahora.getFullYear() - nacimiento.getFullYear();
if (ahora.getTime() < cumpleañosEsteAño.getTime()) {
años--;
}
return años;
}
Después calculamos los meses que además de depender de los puntos mencionados previamente, se resta un mes en caso de que en la fecha actual todavía no se cumpla el mes completo:
const obtenerMeses = (ahora, cumpleañosEsteAño) => {
let meses = 0;
if (ahora.getTime() < cumpleañosEsteAño.getTime()) {
meses = ahora.getMonth() + 12 - cumpleañosEsteAño.getMonth();
} else {
meses = ahora.getMonth() - cumpleañosEsteAño.getMonth();
}
if (ahora.getDate() < cumpleañosEsteAño.getDate()) {
meses--;
}
return meses;
}
Finalmente la cosa se complica un poco más al calcular los días. La función queda así:
const obtenerDias = (ahora, cumpleañosEsteAño) => {
if (ahora.getTime() < cumpleañosEsteAño.getTime()) {
const conteoDeDiasDelMesAnterior = diasEnElMesAnterior(cumpleañosEsteAño);
const diaDeNacimiento = cumpleañosEsteAño.getDate();
const diaDelMesActual = ahora.getDate();
let diasQueVivioEnElMesAnterior = conteoDeDiasDelMesAnterior - diaDeNacimiento;
if (diasQueVivioEnElMesAnterior < 0) {
diasQueVivioEnElMesAnterior = 0;
}
return diasQueVivioEnElMesAnterior + diaDelMesActual;
} else {
if (cumpleañosEsteAño.getDate() <= ahora.getDate()) {
return ahora.getDate() - cumpleañosEsteAño.getDate();
} else {
let diasQueVivioEnElMesAnterior = diasEnElMesAnterior(ahora) - cumpleañosEsteAño.getDate();
if (diasQueVivioEnElMesAnterior < 0) {
diasQueVivioEnElMesAnterior = 0;
}
return diasQueVivioEnElMesAnterior + ahora.getDate();
}
}
}
Ahora que he mostrado las funciones más importantes solo resta usarlas. La función que calcula la edad de una persona usando JavaScript queda así:
const obtenerEdad = (fechaDeNacimientoComoCadena, fechaActual) => {
const nacimiento = new Date(fechaDeNacimientoComoCadena);
const ahora = new Date(fechaActual.getTime());
const cumpleañosEsteAño = obtenerCumpleañosDeEsteAño(fechaDeNacimientoComoCadena, ahora);
const años = obtenerAños(nacimiento, ahora, cumpleañosEsteAño);
const meses = obtenerMeses(ahora, cumpleañosEsteAño);
const dias = obtenerDias(ahora, cumpleañosEsteAño);
return { años, meses, dias };
}
Si te fijas, devolverá un objeto con las propiedades años
, meses
y días
. Tú puedes formatearlas como prefieras.
Veamos un ejemplo. Supongamos que yo nací el 1 de enero de 1970 y quiero calcular mi edad con la fecha actual. El código quedaría así:
const miFechaDeNacimiento = "1970-01-01T00:00:00";
const laFechaActual = new Date();
const miEdadActual = obtenerEdad(miFechaDeNacimiento, laFechaActual);
console.log("Mi edad es: %o", miEdadActual);
Fíjate que la fecha de nacimiento debe ser expresada como una cadena con el formato YYYY-MM-DDTHH:MM:SS.
Al ejecutarla mientras escribo el post, la salida es:
Mi edad es: { 'años': 53, meses: 11, dias: 5 }
Como puede ver, funciona perfectamente.
La función que he mostrado aquí ya está incorporada en la aplicación para calcular la edad de una persona. No sé por qué, pero me costó muchísimo hacer el algoritmo; creo que es de los más complejos que he hecho y no tanto por su complejidad sino porque me equivoqué varias veces y eso formó algo como una bola de nieve.
De cualquier manera, la he probado con varias fechas y funciona correctamente. De hecho aquí tengo un código que muestra la edad que tendría una persona día con día.
Es un código bonus, no voy a explicarlo.
const unDia = 1000 * 60 * 60 * 24;
const unAño = unDia * 365;
const fin = new Date("2024-01-15T00:00:00");
const inicio = new Date("2023-01-01T00:00:00");
const step = unDia;
let nacimiento = "2023-01-01T00:00:00";
console.log("Nació %s", nacimiento);
for (let actual = new Date(inicio.getTime()); actual.getTime() <= fin.getTime(); actual.setTime(actual.getTime() + step)) {
const edad = obtenerEdad(nacimiento, actual);
console.log("%s --> %s", formater.format(actual), edad)
}
Al ejecutarlo:
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…
Esta web usa cookies.
Ver comentarios
Hola Parzibyte.
Como hago para que se muestre el resultado en un DIV de mi página?
He intentado agregando al codigo lo siguiente: document.getElementById('edad').innerHtml = ' '+miEdadActual.
No me muestra el resultado, muestra un error