Algoritmo para calcular la edad [Solucionado]

El algoritmo que usa esDebian para calcular la edad de los usuarios tiene bugs, ya varios usuarios lo han reportado. Si alguien se anima a darnos una mano, les dejo el código (PHP).

$ageTime = mktime(0, 0, 0, $account->profile_nacimiento['day'], $account->profile_nacimiento['month'], $account->profile_nacimiento['year']);
$t = time();
$age = ($ageTime < 0) ? ( $t + ($ageTime * -1) ) : $t - $ageTime;
$year = 60 * 60 * 24 * 365;
$ageYears = floor($age / $year);
print '<br>'. $ageYears .' años';

Tal vez el problema esté en mktime, prueba strtotime

$ageTime = strtotime($account->profile_nacimiento['day'].'-'.$account->profile_nacimiento['month'].'-'.$account->profile_nacimiento['year']);
$t = time();
$age = $t - $ageTime;
$year = 60 * 60 * 24 * 365;
$ageYears = floor($age / $year);
print '<br>'. $ageYears .' años';
Ariel escribió:
$age = ($ageTime < 0) ? ( $t + ($ageTime * -1) ) : $t - $ageTime;

Tal vez sea una obviedad y no me doy cuenta pero ¿Por que es eso?

Mirándo el código (jamás he programado en PHP) inicialmente me extrañó esto:

$year = 60 * 60 * 24 * 365;

Se presupone que todo los años tienen 365 días lo cual introduce un error acumulativo por cada año bisiesto (el 2008 lo fue y tuvo 366 días en lugar 365, más la corrección horaria que metieron en Enero). Esto puede dar lugar que se les adelante la antigüedad anual un día por cada año bisiesto.

Cómo tampoco se cuál es el problema, necesitaría de alguna pista. ¿Ariel puedes decirnos que erróres te han remitido?

Por añadir info útil, diré que el tema de no considerar los años bisiestos no puede ser el único problema. En mi caso, el algoritmo falla así:

Figura como fecha de nacimiento: 4/2/1977
Hoy es: 21/2/2009
Mi edad según el algoritmo es: 31 años

Entre 1977 y 2008 ha habido 8 años bisiestos (80,84,88,92,96,00,04,08) lo que justificaría que el algoritmo se hubiera retrasado 8 días en cambiar mi edad. Sin embargo, ya lleva 17 días de retraso.

EDITO: De hecho, creo que este error haría que la edad se cambiara antes de tiempo, lo contrario de lo que ocurre en mi caso.
EDITO II: He echado un vistazo al algoritmo del enlace de quilloquepasa y me parece un método bastante elegante y eficiente, ya que ahorra cálculos y conversiones al no trabajar con segundos.

No me gusta PHP... (es que tiene menos introspección que la Silvina Luna) pero el error es que estáis calculando la diferencia de tiempo, lo que es un acercamiento erróneo porque es irrelevante saber cuantos segundos pasaron cuando, la mayor parte del tiempo, es más fácil saber cuantos años pasaron (que es lo que queremos averiguar).

#esto es pseudocodigo
año_hoy, mes_hoy, día_hoy = date()
año_nacimiento, mes_nacimiento, día_nacimiento = perfil.get_fecha_nacimiento()
hoy = año_hoy +  mes_hoy * .01  + día_hoy * .0001
nacimiento = año_nacimiento +  mes_nacimiento * .01  + día_nacimiento * .0001
edad = entero(hoy - nacimiento)

.
Una pregunta, ¿el algoritmo falla para los nacidos antes del 1 de enero de 1970? silbo

El algoritmo es muy simplista y tiene muchas fallas, asi que me parece que la solucion va a ser utilizar otro.

Ariel escribió:

El algoritmo es muy simplista y tiene muchas fallas, asi que me parece que la solucion va a ser utilizar otro.

Es que tiene que ser sencillo. No necesitas conocer el tiempo que ha transcurrido desde la fecha de nacimiento y luego convertirlo a años (teniendo en cuenta las diferencias entre las duraciones de los meses del año y entre años bisiestos y no bisiestos) cuando puedes operar con años directamente.

Point_to_null escribió:
Ariel escribió:

El algoritmo es muy simplista y tiene muchas fallas, asi que me parece que la solucion va a ser utilizar otro.

Es que tiene que ser sencillo. No necesitas conocer el tiempo que ha transcurrido desde la fecha de nacimiento y luego convertirlo a años (teniendo en cuenta las diferencias entre las duraciones de los meses del año y entre años bisiestos y no bisiestos) cuando puedes operar con años directamente.

Cierto, eso simplifica la comparación.
Bastaría con obtener la fecha de sistema y restar al año de la fecha el del año de nacimiento para obtener una primera edad, luego sólo hay que comprar entre si los meses de ambas fechas y los días para saber si ha de restarse un año o no al resultado.

La única pega con esto son los nacidos el 29 de febrero, supongo que cumplen los años el 28 de febrero los años no bisiestos.

nerve_net escribió:
Point_to_null escribió:
Ariel escribió:

El algoritmo es muy simplista y tiene muchas fallas, asi que me parece que la solucion va a ser utilizar otro.

Es que tiene que ser sencillo. No necesitas conocer el tiempo que ha transcurrido desde la fecha de nacimiento y luego convertirlo a años (teniendo en cuenta las diferencias entre las duraciones de los meses del año y entre años bisiestos y no bisiestos) cuando puedes operar con años directamente.

Cierto, eso simplifica la comparación.
Bastaría con obtener la fecha de sistema y restar al año de la fecha el del año de nacimiento para obtener una primera edad, luego sólo hay que comprar entre si los meses de ambas fechas y los días para saber si ha de restarse un año o no al resultado.

La única pega con esto son los nacidos el 29 de febrero, supongo que cumplen los años el 28 de febrero los años no bisiestos.

hmmmmm, vaya. Si que estás atento. Legalmente (creo) cumplen el 28 de febrero... en este algoritmo cumplirían terminado el 28 de febrero, es decir el 1 de marzo. Creo que se puede poner una excepción donde internamente se reemplace 29 de febrero por 28 de febrero para realizar el calculo.