[offtopic] Algoritmia, fechas y decimal

26/08/2003 - 13:02 por Gandalf | Informe spam
Hola, me gustaría conocer un algoritmo que me permitiese calcular el nº de
días transcurridos desde el inicio de la era cristiana hasta una fecha y a
la inversa, así como el día de la semana de un fecha.

Tengo el algoritmo para calcular el nº de días y el día de la semana pero no
la función inversa:

Calcular el nº de días transcurridos desde el principio de la era cristiana
hasta una fecha
La Formula es:

N=D+2*M+INT(3*(M+1)/5)+A+INT(A/4)-G



Dónde:

Nà es el nº de días transcurridos

Dà es el día de la fecha

Mà es el mes de la fecha

Aà es el año de la fecha

Gà es una constante



Para realizar los cálculos debemos tener en cuenta lo siguiente:



1.. Si la fecha es del calendario juliano (hasta 4 de octubre de 1582);
G=0
2.. Si la fecha es del calendario gregoriano (desde el 15 de octubre de
1582); G=INT(A/100)-INT(A/400)-2
3.. Si es el Mes es Enero o Febrero (tanto para fechas julianas como
gregorianas) entonces; M=M+12 y A=A-1


Calcular el día de la semana a partir del nº de Días


R=N-7*INT(N/7)+1



R=1 à Sábado

R=2 à Domingo

R=3 à Lunes

Etc.



También he encontrado el siguiente código en C, pero sólo funciona con
fechas gragorianas y no me da el día de la semana:



const int ENERO = 1;

const int DiasDelMes[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
31};

bool EsBisiesto(long aaaa) {
if (0==(aaaa%100))
return 0==(aaaa%400);
return 0==(aaaa%4);
}

long PasaDDMMAAAAaDDDDDDD(long ddmmaaaa) {
long ddmm, dd, mm, aaaa, ddd;
int i;
ddmm = ddmmaaaa/10000l;
aaaa = ddmmaaaa%10000l;
dd = ddmm/100;
mm = ddmm%100;
for (ddd = dd, i = ENERO; i < mm; i++)
ddd += DiasDelMes[i];
if (EsBisiesto(aaaa) && (mm > 2))
ddd++;
return (((aaaa-1501l)*36525l)/100l - 29872l + ddd - (aaaa-1501l)/100l +
(aaaa-1201l)/400l);
}

long PasaDDDDDDDaDDMMAAAA(long ddddddd) {
long d,aaaa,ddd;
d = ddddddd + 139444l + (ddddddd*100l+13944400l)/3652425l -
(ddddddd*100l+13944400l)/3652425l/4l;
aaaa = d*100l/36525l;
aaaa += ((aaaa*36525l)==d) ? 1200l : 1201l;
ddd = d - (aaaa-1201l)*36525l/100l;
int mm;
for (mm=ENERO; ddd>DiasDelMes[mm]; mm++) {
ddd-=DiasDelMes[mm];
if (mm==1)
if (EsBisiesto(aaaa))
if (ddd==DiasDelMes[2]+1) {
mm++;
break;
}
else if (ddd>DiasDelMes[2]+1)
ddd--;
}
if (ddd==0) {
ddd1;
mm;
aaaa--;
}
return ddd*1000000l+mm*10000l+aaaa;
}

bool EsFechaValida(long ddmmaaaa) {
return ddmmaaaa==PasaDDDDDDDaDDMMAAAA(PasaDDMMAAAAaDDDDDDD(ddmmaaaa));
}

long IncrementaFecha( long ddmmaaa, long Incremento) {
return PasaDDDDDDDaDDMMAAAA(PasaDDMMAAAAaDDDDDDD(ddmmaaaa)+Incremento);
}


Si alguien tiene información sobre el tema se lo agradeceria.



Por otra parte tengo curiosidad por saber el algoritmo que utiliza C# para
dividir dos números tipo Decimal.



Un Saludo a todos y gracias.

Carlos Barreira.
 

Leer las respuestas

#1 Octavio Hernández
02/09/2003 - 11:50 | Informe spam
Carlos,

Por otra parte tengo curiosidad por saber el algoritmo que utiliza C# para
dividir dos números tipo Decimal.



Para estas cosas, lo mejor es que te descargues de la web el Rotor, donde
está el código fuente de la implementación de referencia de .NET. El fichero
donde se implementa la aritmética decimal se llama decarith.cpp (está en
C++). No he tenido tiempo de verlo en detalle, pero el código fuente incluye
comentarios que seguramente te dirán algo.

Tengo el algoritmo para calcular el nº de días y el día de la semana pero


no
la función inversa.



A ese algoritmo le decíamos 'fórmula de Zener' en mis tiempos de estudiante.
No recuerdo que existiera una función inversa, haría que buscar en
Internet...

Salu2,

Octavio

Preguntas similares