Ir al contenido

Discusión:Algoritmia/Algoritmo para calcular el día de la semana

Contenido de la página no disponible en otros idiomas.
Añadir tema
De Wikilibros, la colección de libros de texto de contenido libre.
Último comentario: hace 14 años por JViejo en el tema Fuente primaria

Obtención de la fecha absoluta

[editar]

La obtención de la fecha absoluta (en días) que se propone en el texto me parece innecesariamente convoluta.

Se resta 1 al año, se multiplica por 365 y se añaden tantos días como años bisiestos hayan transcurrido (Teniendo en cuenta que todo ello es válido sólo para fechas posteriores a 1582). Para ello basta usar (a-1)\4 - (a-1)\100 + (a-1)\400, donde (\) indica divisiones son enteras. Es decir se añaden los años múltiplos de 4, se restan de ellos los múltiplos de 100 y se añaden de nuevo los múltiplos de 400. A continuación evaluamos el día juliano a partir de la tabla de días transcurridos hasta el final del mes anterior al considerado y sumamos los días del mes. Por último, si el año es bisiesto y el mes es al menos marzo, añadimos un día. Esta fecha absoluta módulo 7 nos da el día de la semana. --Mcovas (discusión) 11:13 29 dic 2008 (UTC)Responder

De hecho, en una vuelta de tuerca probablemente innecesaria, podemos ver que en puridad, la formula del texto no funciona para años menores a 301 (No es que importe mucho si se tiene la precaución de advertir que el algoritmo sólo es valido para fechas posteriores a 1582). La fórmula ((a-1)\100 + 1)\4 da cero en división entera para el año 300. 299\100 es 2 y (2+1)\4 es 0. Por tanto si se pretendía restar 3 de cada 4 múltiplos de 100 no ha funcionado.

Me parece que 365*(a-1)+(a-1)\4-(a-1)\100+(a-1)\400 es más simple.

La tabla para determinar el día juliano es esta forma ordenado de la siguiente manera:

Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic
0 31 59 90 120 151 181 212 243 273 304 334

Entiendo que se dispone siempre de una calculadora. Si hay que hacer cálculos manuales supongo que puede ser más rápido usar la aproximación de extraer restos parciales. --Mcovas (discusión) 11:39 29 dic 2008 (UTC)Responder

Un Caso representativo

[editar]

Implementé el algoritmo, y por ejemplo para el nacimiento de Albert Einstein no funcionó correctamente. El nacimiento de Einstein ocurrió el 14 de marzo de 1879.

El año 1879 no es bisiesto, por lo que en la tabla de Módulos M, Marzo tiene M=3

paso 1.- (R1).

paso 2.- (Sólo parte entera).

paso 3.- (Sólo parte entera).

paso 4.- (Sólo parte entera).

paso 5.- (R2).

paso 6.- M=3 (R3).

paso 7.- (R4).

paso 8.- .


El resultado es cero, lo indicaría un Domingo. Pero Einstein nacio un Viernes. Vease

En tal sentido, parece que el algoritmo mostrado contiene un error, o hay una limitación ademas del año de adopción del calendario Gregoriano.

Existe este otro método (ver) que según la página, se le adjudica la autoría a Lewis Carroll. Éste si funcionó con el nacimiento de Einstein.

Para aclarar

[editar]

Efectivamente Einstein nació un día viernes

Podríamos colocar este código en un script de VB (.vbs)


A = 1879
D = 14
DM = 1 'correponde a marzo

MsgBox ((A - 1) Mod 7 + ((A - 1) \ 4 - 3 * (((A - 1) \ 100 + 1) \ 4)) Mod 7 + DM Mod 7 + D Mod 7 + D Mod 7) Mod 7


Lo que pasa es que en el cálculo de prueba de nuestro amigo MCovas no se ha utilizado correctamente los paréntesis. El número 3 incluido en la fórmula tiene como función eliminar los siglos no bisiestos.

Este es un algortimo de elbaroación propia y seguramente deberá pulirse.

Un comentario adidional. La sugerencia de la utilización de 365*(a-1)+(a-1)\4-(a-1)\100+(a-1)\400 no es aplicable, debido a que se produce un error de overflow y por eso yo he utilizado propiedades de la artimética modular.— El comentario anterior es obra de Cpb.sos (disc. • contr.), quien olvidó firmarlo. JViejo (discusión) 20:07 12 dic 2009 (UTC)Responder

Fuente primaria

[editar]

Saludos, Cpb.sos. Muchas gracias por tu aportación a esta enciclopedia. Lamento decirte que en las políticas de Wikipedia no se admiten trabajos de elaboración propia. Me consta que tu algoritmo ha ayudado a muchos usuarios, pero Wikipedia no es el lugar para publicarlo. El artículo será borrado a menos que aportes referencias de dónde ha salido la información, algo que temo vaya a ser imposible. Te animo a buscar otros algoritmos que ya existan y ampliar la información al respecto o crearles un nuevo artículo. --JViejo (discusión) 20:07 12 dic 2009 (UTC)Responder

Procedo a solicitar su borrado, que se hará efectivo en una semana si no hay objeciones. Por favor, salvad la información que proceda de una fuente fiable para mejorar y ampliar el artículo Algoritmo para calcular el día de la semana. Gracias. — JViejo (dime) 16:00 15 ene 2010 (UTC)Responder

Otra Formula para obtener el día de la semana de cualquie fecha, sin necesidad de marcadores o tablas.

[editar]

Se obtiene el año, mes y día de una fecha a buscar el día de la semana

En la siguiente ecuación se obtiene la era, da 0 si los números del año son positivos “año después de Cristo”; y 1 si los números del año son negativos “año antes de Cristo”.
era = [truncar(e(-0.1/año))] mod 2


Con la siguiente ecuación se obtiene si el mes corresponde al año anterior (1) o al año actual (0), los meses de enero y febrero corresponde al año anterior los restantes al actual. Solo da como resultado 0 o 1.
añoAnterior = truncar(([mes + 9] mod 12) / 10)


Con esto se obtiene el año actual y con el resultante se obtiene el día del juicio “Doomsday” con las siguientes formulas
añoActual = año + era - añoAnterior
diaJuicio = [(añoActual mod 4) + (truncar(añoActual / 4) * 4) + (truncar(añoActual / 4))] mod 7


Con la siguiente formula tomamos los días totales transcurridos desde el primero de marzo, en caso de ser fecha de enero o febrero, esta misma formula dará los días transcurridos desde el 1 de marzo del año anterior.
diasTranscurridos = truncar(([mes + 9] mod 12) * (337 / 11)) - truncar(([[mes + 9] mod 12] mod 5 ) / 4) + dia


Con los días transcurridos obtenemos el residuo de 7
residuo = diasTranscurridos mod 7


Por último para obtener el día de la semana de la fecha que estamos buscando se suman el diaJuicio y residuo y al resultado se saca el residuo de 7.
diaSemana = [diaJuicio + residuo] mod 7


El resultado se puede expresar de la siguiente tabla

0lunes
1martes
2miércoles
3jueves
4viernes
5sábado
6domingo


formula en excel: D74 es el año; E74 es el mes; F74 es el dia
=RESIDUO(RESIDUO(RESIDUO(((D74+RESIDUO(TRUNCAR(EXP(-0.0000001/D74)),2))-TRUNCAR(RESIDUO(E74+9,12)/10)),4) + ((TRUNCAR(((D74+RESIDUO(TRUNCAR(EXP(-0.0000001/D74)),2))-TRUNCAR(RESIDUO(E74+9,12)/10))/4)*4)+(TRUNCAR(((D74+RESIDUO(TRUNCAR(EXP(-0.0000001/D74)),2))-TRUNCAR(RESIDUO(E74+9,12)/10))/4))),7) + RESIDUO(REDONDEAR(RESIDUO(E74+9,12)*(337/11),0)-TRUNCAR(RESIDUO(RESIDUO(E74+9,12),5)/4)+F74,7),7)


Ejemplo
Fecha = 1970/11/04, año = 1970, mes = 11, dia = 4


Resultados:
como el año es de nuestra era entonces era = 0
como el mes es noviembre entonces añoAnterior = 0
añoActual = 1970 + 0 – 0 = 1970

diaJuicio = ((1970 mod 4) + (truncar(1970/4) * 4) + truncar(1970/4)) mod 7
diaJuicio = (2 + 1968 + 492) mod 7
diaJuicio = (2462) mod 7
diaJuicio = 5 que corresponde a Viernes para el año de 1970

diasTranscurridos = truncar(([11+9] mod 12)*(337/11)) – truncar( ([[11+9] mod 12 ]] mod 5) / 4) + 4
diasTranscurridos = truncar((20 mod 12)*(30.6363…)) – truncar( ([20 mod 12 ]] mod 5) / 4) + 4
diasTranscurridos = truncar(8*(30.6363…)) – truncar( (8 mod 5) / 4) + 4
diasTranscurridos = 245 – 0 + 4 = 249

residuo = 249 mod 7 = 4

diaSemana = (5 + 4) mod 7 = 2 que corresponde a Miércoles

Procedo a corregir la fórmula de excel ya que contiene, además de algún error de argumentos los números decimales al estilo anglosajón (con . en lugar de con , como acepta nuestro excel). La fórmula correcta (y probada) es:

=RESIDUO(RESIDUO(RESIDUO(((D74+RESIDUO(TRUNCAR(EXP(-0,0000001/D74));2))-TRUNCAR(RESIDUO(E74+9;12)/10));4) + ((TRUNCAR(((D74+RESIDUO(TRUNCAR(EXP(-0,0000001/D74));2))-TRUNCAR(RESIDUO(E74+9;12)/10))/4)*4)+(TRUNCAR(((D74+RESIDUO(TRUNCAR(EXP(-0,0000001/D74));2))-TRUNCAR(RESIDUO(E74+9;12)/10))/4)));7) + RESIDUO(REDONDEAR(RESIDUO(E74+9;12)*(337/11);0)-TRUNCAR(RESIDUO(RESIDUO(E74+9;12);5)/4)+F74;7);7)