Congruencia de Zeller




La congruencia de Zeller es un algoritmo ideado por Julius Christian Johannes Zeller un sacerdote protestante alemán que vivió en el siglo XIX. Zeller observó que existía una dependencia entre las fechas del calendario gregoriano y el día de la semana que les correspondía. A raíz de esa observación, obtuvo (se dice que por tanteo), esta fórmula, en apariencia mágica, que lleva su nombre, para calcular el día de la semana de cualquier fecha del calendario.

Para el calendario gregoriano la congruencia de Zeller es:




para el calendario juliano es:



donde
h es el día de la semana (0 = sábado, 1 = domingo, 2 = lunes,...),
q es el día del mes,
m es el mes,
J es la centuria (es realidad ⌊año / 100⌋) y
K el año de la centuria (año mod 100).
Enero y febrero se cuentan como meses 13 y 14 del año anterior. Observe, que el 2 de enero de 2013, es m=13; año=2012
Es oportuno recordar que la función mod es el residuo que queda de la división de dos números.
En las implementaciones informáticas en las que el módulo de un número negativo es negativo, la manera más sencilla de obtener un resultado entre 0 y 6 es reemplazar - 2 J por + 5 J y - J por + 6 J.

Algoritmo Z(y, m, d)
Entrada: El año y, mes m (1 ≤ m ≤ 12) y día d (1 ≤ d ≤ 31).
Salida: El día de la semana.
t ← (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4) 
n ← (domingo, lunes, martes, miércoles, jueves, viernes, sábado)
if m < 3 
y ← y - 1 
w ← (y + ⌊y/4⌋ - ⌊y/100⌋ + ⌊y/400⌋ + tm-1 + d) mod 7 
devolver nw


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Zeller_I_Forms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

        }

        string[] dias = new string[] { " Domingo ", " Lunes ", " Martes ", " Miercoles ", " Jueves ", " Viernes ", " Sabado " };

        private void button1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int dia, mes, año;
            dia = int.Parse(textBox1.Text);
            mes = int.Parse(textBox2.Text);
            año = int.Parse(textBox3.Text);

            if ((dia < 32) && (mes < 13) && (año < 10000))
            {
                int a = (14 - mes) / 12;
                int y = año - a;
                int m = mes + 12 * a - 2;
                int d = (dia + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12) % 7;
                textBox4.Text = dias[d];

            }
        }
    }

}


Enlace de descarga:

https://code.msdn.microsoft.com/Congruencia-de-Zeller-48268c0a?redir=0

Una forma más fácil de ver el mismo desarrollo es la siguiente


a = (14 - Mes) / 12
y = Año - a
m = Mes + 12 * a - 2

Para el calendario Juliano:
d = (5 + dia + y + y/4 + (31*m)/12) mod 7

Para el calendario Gregoriano:
 d = (día + y + y/4 - y/100 + y/400 + (31*m)/12) mod 7
El resultado es un cero (0) para el domingo, 1 para el lunes… 6 para el sábado

Ejemplo, ¿En qué día de la semana cae el 2 de agosto de 1953??
' a = (14 - 8) / 12 = 0
' y = 1953 - 0 = 1953
' m = 8 + 12 * 0 - 2 = 6
' d = (2 + 1953 + 1953 / 4 - 1953 / 100 + 1953 / 400 + (31 * 6) / 12) Mod 7
'   = (2 + 1953 +  488   -    19   +     4    +    15    ) mod 7
'   = 2443 mod 7
'   = 0
'  El valor cero(0) corresponde al domingo.


La norma ISO 8601:2004, en su apartado 3.2.2 define el código de los días de la semana así como los nombres de los días de la semana (evidentemente están en inglés) pero lo que interesa resaltar es que la numeración que propone el estándar no coincide con la numeración que proporciona el algoritmo de Zeller (y por tanto, la función [DayOfWeek]) la diferencia está en la forma de contar, el algoritmo de Zeller proporciona valores del 0 (domingo) 1 lunes… hasta al 6(sábado), mientras que la norma ISO 8601, dice que los valores van desde el 1 lunes al 7 domingo.



No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.