Algoritmo para calcular la diferencia entre dos fechas

La cosa es que necesitaba un algoritmo que calcule la diferencia entre dos fechas. A primera vista parece sencillo pero el problema viene que el resultado tengo que devolverlo en meses. Supongamos que trabajamos con timestamp (cada fecha viene determinada por un valor en segundos, concretamente los segundos transcurridos desde el 1 de enero de 1970)

Problemas:

- No todos los meses tienen el mismo numero de días luego dividir entre el numero de segundos que tiene un mes es incorrecto.

- No todos los años tienen el mismo numero de dias.

- La fracción restante, vamos los decimales, se tienen que referir al ultimo mes. Por ejemplo no es lo mismo que nos queden 2 dias de febrero que de abril.

Llevo un buen rato rompiéndome la cabeza y no se me ocurre nada.

La primera aproximacion es obvia. Restamos las dos fechas y dividimos entre el numero de segundos de un mes. El problema aqui es ¿cuantos segundos tiene un mes?

La segunda es irnos a los años. Primero restamos las fechas y calculamos el numero de años. Multiplicando por 12 siempre tendremos un numero exacto de meses. Ahora nos sobra el resto. Con eso ya no se me ocurre nada.
En vez de hacerlo con timestamp se podria hacer directamente con las fechas, vas restando años, meses y dias. El problema es que la forma de restar varia en funcion de si el mes de la segunda fecha esta antes o despues del de la primera, y lo mismo pasa con los dias, ademas puede que ser que el mes sea el mismo y cambien los dias y el año, con lo que habria que tener en cuenta que mes es.
Hay unas cuantas posibilidades en funcion de como sean las fechas (creo que seis), pero comprobando eso y luego restando en funcion de ello creo que se puede hacer.
No se si me habre explicado bien, que a estas horas las neuronas ya andan dormidas.
La cosa es que estaba buscando algo que con minimas variaciones me sirviera para todo pero creo que voy a tener que hacer lo que dices.

La verdad es que el sistema del calendario no está pensado para esto. Un rato llevo peleándome con la diferencia de dos fechas en dias para darme cuenta que no todos los dias tienen 24 horas.

:D :D :D
Yo con timestamp se calcular cuantos dias hay desde una fecha a otra, supongo que lo tuyo es mas complicado pero si te sirve dimelo y te digo como lo hago.
yo para eso inventaria un tipo de unidad nueva llamada 'monthstamp', para eso convertiria los timestamp en fechas reales

---------------------------------
int monthstamp1, monthstamp2, diferencia;
timestamp time1, time2;

//year(valor) devuelve el año del timestamp 'valor'
//month(valor) devuelve el numero de mes del timestamp 'valor'
monthstamp1=(year(time1)*12)+month(time1);
monthstamp2=(year(time2)*12)+month(time2);
diferencia=monthstamp2-monthstamp1;
if(day(time1)>=day(time2)) {
//si ademas dias(time1) es posterior al tiempo de dias de time2
//significa que queda menos de un mes para que cumpla ese dia
diferencia=diferencia-1;
}

----------------------------------
esa seria la forma bruta, la forma 'optima' seria esta:

------------------------------
int diferencia,temp;
timestamp time1, time2;

temp=time2-time1;
diferencia=((year(temp)-1970)*12)+month(temp);

---------------------------
listo, tu veras como los dos algoritmos te dan el mismo resultado.
Pues si, creo que es necesario hacer un 'loqueseastamp' para dias, meses o años. Una putadilla.
el problema es que un 'daystamp' es muy complicado, porque no todos los meses tienen el mismo numero de dias. ni siquiera los años tienen el mismo numero de dias, algunos tienen 365 y otros 265 dias... (años bisiestos).

sin embargo, con el segundo algoritmo si es posible calcular cualquier diferencia de dias, porque precisamente todos los dias tienen 24 horas, todas las horas tienen 60 minutos y todos los minutos tienen 60 segundos. las correcciones horarias segun horario de verano o invierno tambien estan normalizadas y si quisieras agregarlas con consultar el algoritmo que las genera(creo que era la noche del primer domingo de la entrada de la primavera o algo asi, aplicando el algoritmo al año, te decia exactamente que dia caia la correccion horaria)

sin embargo los meses son mas complicados, aunque no imposibles...
La cosa podría ser aplicar la correccion horaria a posteriori pero si nos ponemos así tambien podríamos suponer todos los meses de 31 dias y aplicar una correccion mensual a posteriori. Con la diferencia que para los días es 2 veces una por dia y para los meses 5 una por mes con numero de dias distinto a 31.

Igual computacionalmente merece más la pena lo segundo.
Las fechas las tengo en timestamp pero pasarlas a formato legible es inmediato ya que el sistema proporciona funciones para ello.

Estoy haciendo una web que maneja diagramas de Gantt y tal y para calcular lo que le voy a mostrar al usuario que dura cada tarea. La cosa es que quería que se mostrase en distintas unidades según la escala que esté usando.
f5inet escribió:el problema es que un 'daystamp' es muy complicado, porque no todos los meses tienen el mismo numero de dias. ni siquiera los años tienen el mismo numero de dias, algunos tienen 365 y otros 265 dias... (años bisiestos).

sin embargo, con el segundo algoritmo si es posible calcular cualquier diferencia de dias, porque precisamente todos los dias tienen 24 horas, todas las horas tienen 60 minutos y todos los minutos tienen 60 segundos. las correcciones horarias segun horario de verano o invierno tambien estan normalizadas y si quisieras agregarlas con consultar el algoritmo que las genera(creo que era la noche del primer domingo de la entrada de la primavera o algo asi, aplicando el algoritmo al año, te decia exactamente que dia caia la correccion horaria)

sin embargo los meses son mas complicados, aunque no imposibles...



que yo sepa, los años bisiestos no tienen cien dias menos que los no bisiestos :p

es solo por tocar la moral :D

saludos compañeros!
Convertimos las fechas en días... Si tenemos los segundos pasarlos a dias es fácil.


Como ya dije antes esto no es tan trivial como parece. Hay un día al año que tiene 25 horas y un dia que tiene 23.
10 respuestas