Es todo un asunto la aritmética con fechas :)
Yo había solucionado un asunto parecido alguna vez en AutoIt (un lenguaje sencillo de scripting para windows). Lo que hice fue usar funciones ya incluidas en el lenguaje que permitían convertir una fecha determinada a lo que se llama Fecha Juliana, que luego era sencillo de operar y re-convertir a formato de fecha.
Otro método es tomar una fecha como referencia y calcular el número de días transcurridos desde entonces a las dos fechas con las cuales quieres operar y luego operar con estos números normalmente.
Bueno yo hice en C hace un tiempo para la facultad unas funciones que calculan la diferencia de dos fechas con mucha presición. Lo más importante en el código es la función FechaADias(), que lo que hace es obtener el número de días desde el 1/01/1904. Luego con FechaDif() se puede calcular la diferencia en días entre esas dos fechas.
Código C:
Ver original#include <stdio.h>
struct fecha{
int dia;
int mes;
int anio;
};
long FechaDif(int , int, int, int, int, int);
long FechaADias(int, int, int);
void main()
{
struct fecha ingreso, alta;
long dif;
printf("\nIngrese 1° fecha [dia mes año]:"); scanf("%d %d %d",&ingreso.
dia,&ingreso.
mes,&ingreso.
anio); printf("\nIngrese 2° fecha [dia mes año]:"); scanf("%d %d %d",&alta.
dia,&alta.
mes,&alta.
anio);
dif = FechaDif(ingreso.dia,ingreso.mes,ingreso.anio,
alta.dia,alta.mes,alta.anio);
printf("\n%ld dias de diferencia.",dif
); }
long FechaDif(int dia1, int mes1, int anio1, int dia2, int mes2, int anio2)
{
/* Meses con 31:
Enero(1) Marzo(3) Mayo(5) Julio(7) Agosto(8) Octubre(10) Diciembre(12)
Meses con 30:
Abril(4) Junio(6) Setiembre(9) Noviembre(11)
Meses con 28:
Febrero(2)
*/
long dias1,dias2,dif;
printf("\n\n%d %d %d\n\n",dia1
,mes1
,anio1
); printf("\n\n%d %d %d\n\n",dia2
,mes2
,anio2
);
//Chequear valores.
if((mes1>12)|(mes2>12))
return -1;
if((mes1==1)|(mes1==3)|(mes1==5)|(mes1==7)|(mes1==8)|(mes1==10)|(mes1==12))
if(dia1>31)
return -1;
if((mes2==1)|(mes2==3)|(mes2==5)|(mes2==7)|(mes2==8)|(mes2==10)|(mes2==12))
if(dia2>31)
return -1;
if((mes1==4)|(mes1==6)|(mes1==9)|(mes1==11))
if(dia1>30)
return -1;
if((mes2==4)|(mes2==6)|(mes2==9)|(mes2==11))
if(dia2>30)
return -1;
if(mes1==2 && dia1>29)
return -1;
if(mes2==2 && dia2>29)
return -1;
dias1 = FechaADias(dia1,mes1,anio1);
dias2 = FechaADias(dia2,mes2,anio2);
//devolver la diferencia positiva
dif = dias2 - dias1;
if(dif<0)
return ((long)(-1*dif));
return dif;
}
long FechaADias(int dia, int mes, int anno){
/*Devuelve la cantidad de días desde el 1/01/1904
No verifica datos. Llamada desde FechaDif()
intervalo permitido: 1904-2099
*/
long cant_bic,cant_annos,cant_dias;
int no_es_bic;
//verificar la cantidad de biciestos en el periodo (div entera)
//+1 p/contar 1904
cant_bic = (anno-1904)/4 + 1;
no_es_bic = anno%4;
//calcular dias transcurridos hasta el 31 de dic del año anterior
cant_annos = anno-1904;
cant_dias = cant_annos*365 + cant_bic;
//calcular dias transcurridoes desde el 31 de dic del año anterior
//hasta el mes anterior al ingresado
int i;
for(i=1;i<mes;i++){
if((i==1)|(i==3)|(i==5)|(i==7)|(i==8)|(i==10)|(i==12))
cant_dias+=31;
if((i==4)|(i==6)|(i==9)|(i==11))
cant_dias+=30;
if(i==2)
{
if(no_es_bic)
cant_dias+=28;
else
cant_dias+=29;
}
}
//sumarle los dias transcurridos en el mes
cant_dias+=dia;
return cant_dias;
}
La función FechaDif() devuelve -1 si hay algún error. Es fácil convertir a JavaScript. Si realmente no podés me puedo tomar unos minutos y hacerlo por vos.
Ojo que el código tiene copyright, me costó mucho trabajo en ese momento! ;)