Bueno, primero agradezco tu pregunta porque me has hecho encontrarle un error grave a mi ahora antiguo cálculo de diferencia de fechas. Tenía un error muy grosero pero afortunadamente no afecta al funcionamiento general del sistema.
Para comenzar tenemos que reducir todo a la unidad que es el día. Entonces tendríamos que calcular cuántos días representan una fecha dada desde el inicio del calendario. Es decir que el día 1 es el 01/01/0001. Si podemos calcular los días transcurridos desde esa fecha hasta la fecha dada y luego hacemos la resta entre los dos obtendremos la cantidad de días de diferencia entre las dos fechas ¿cierto?, cierto.
Pero hay dos problemas. El primero son los años biciestos, el segundo es el agujero que hay entre el cambio del calendario juliano al gregoriano. Actualmente usamos el calendario gregoriano que incluye los años biciestos mientras que el juliano (en uso hasta el año 1582) no tenía años biciestos (todos los años eran de 364 días).
Después de darle vueltas al tema por horas decidí que lo mejor es convertir la fecha actual en calendario gregoriano al juliano, para sacarme de encima los años biciestos y luego compensar los días de más que tuvo el año 1582.
Y llegué a esta función.
function CalcJuliano(dia, mes, ano: integer): longint;
var
anospn, aux: real;
c : real;
begin
anospn:= 1.0 * ano;
aux:= (1.0 * mes - 2.85) / 12;
anospn:= anospn + aux;
if ((longint(ano) * 10000) + (mes * 100) + dia) <= 15821004 then
c:= 0.75 * 2
else
c:= 0.75 * trunc(anospn / 100);
CalcJuliano:= trunc(trunc(trunc(367 * anospn) - 1.75 * trunc(anospn) + dia) - c) + 1721115;
end;
Toma una fecha que debe ser válida, hace la traslación de la misma a días en el calendario juliano y devuelve la cantidad de días entre la fecha dada y el día 1 de ese calendario. No me pidas que explique paso a paso todos los cálculos, algunas constantes son el resultados de otros cálculos confiables que encontré en la red.
Habiendo convertido todo a cantidad de días "absolutos", ya no importa que la fecha dada sea en calendario gregoriano. El resto es convertir la otra fecha y calcular la diferencia:
type
TFecha=record
dia, mes, ano: integer;
end;
...
function RestarFecha(f1, f2: tfecha): longint;
begin
RestarFecha := CalcJuliano(f1.dia, f1.mes, f1.ano) - CalcJuliano(f2.dia,f2.mes,f2.ano);
end;
Lo que falta es obvio:
var
fecha1, fecha2: TFecha;
begin
fecha1.dia:=01;
fecha1.mes:=01;
fecha1.ano:=2006;
fecha2.dia:=01;
fecha2.mes:=01;
fecha2.ano:=2004;
writeln ('Diferencia en días: ', RestarFecha(fecha1, fecha2));
end.