Kalendarz wieczny, także kalendarz perpetualny – tabela lub wzór pozwalająca obliczyć określony dzień tygodnia w kalendarzu gregoriańskim dla każdej daty w postaci: dzień miesiąca, miesiąc, rok.

Wzory liczące dni tygodnia Metoda konwergencji Zellera Kalendarz stuletni daje sprowadzić się do dość prostego algorytmu, który w pierwotnej wersji został zaproponowany przez Christiana Zellera w kolejnych publikacjach, które ukazywały się w latach 1882–1886 (m.in. w Acta Mathematica, vol.9 (1886–1887), pp.131–6). Formuła zaproponowana dla Zellera działa dla kalendarza gregoriańskiego oraz juliańskiego, jednak była przeznaczona do liczenia przez ludzi, co może rodzić problemy przy liczeniu reszty z dzielenia dla niektórych dat.

Uproszczony wzór Keitha Algorytm Zellera został uproszczony i opublikowany w 1990 roku przez matematyka Mike'a Keitha do postaciJournal of Recreational Mathematics, Vol. 22, No. 4, 1990, p. 280:

gdzie: – część całkowita liczby (podłoga); – funkcja modulo (reszta z dzielenia); – () numer miesiąca (od 1 – styczeń do 12 – grudzień); – () numer dnia miesiąca; – () rok; – rok z poprawką: ; – () korekta: .

Wynikowy nr dnia tygodnia należy przeliczać następująco: 0 – niedziela, 1 – poniedziałek, … 6 – sobota.

Zaletą wzoru Mike'a Keitha jest możliwość zapisania go w języku programowania C w jednej linii liczącej 45 znaków, co w funkcji wygląda tak:int keith(int d, int m, int y) { return (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7; }Formuła ta dotyczy obliczeń kalendarza gregoriańskiego.

Wady uproszczonych wzorów Należy zwrócić uwagę, że kalendarz gregoriański został wprowadzony w katolickich krajach w XVI wieku oraz stopniowo w innych krajach Europy w kolejnych wiekach. Obliczenia kalendarza w uproszczonych wzorach nie biorą tego pod uwagę i zakładają, że liczy się dni wstecznie niezależnie tego, czy dany kalendarz obowiązywał, czy nie. Analogiczne obliczenia można wykonać dla kalendarza juliańskiego, a faktyczny dzień tygodnia musiałby być obliczony zależnie od tego który kalendarz obowiązywał w danym tygodniu.

Mimo ew. uwzględnienia obowiązującego kalendarza algorytm Zellera i pokrewne nie biorą pod uwagę anomalii takich jak krótki wrzesień w 1752 roku, który również musiałby być uwzględniony przy datach sprzed XIX wieku m.in. w Wielkiej Brytanii.

Przykładowe implementacje Poniżej podane są przykładowe implementacje w podstawowych językach programowania.

Implementacja w Pascalu Zapis w języku Pascal algorytmu obliczania dnia tygodnia w kalendarzu gregoriańskim (bez ww. poprawki dla kalendarza juliańskiego): function dzien_tygodnia(Year,Month,Day:word):string; var M,C,D,N:integer; const week:array[0..6]of string=('Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'); begin M := 1 + (Month + 9) mod 12 ; if M>10 then Dec(Year) ; C := Year div 100 ; D := Year mod 100 ; N := ((13*M-1) div 5 + D + D div 4 + C div 4 + 5*C + Day) mod 7 ; dzien_tygodnia:=week[N]; end; gdzie Month, Day = numer miesiąca i dnia miesiąca, Year = czterocyfrowy zapis roku, N = kod dnia tygodnia poczynając od niedzieli (0) do soboty (6), mod = funkcja modulo, div = funkcja dzielenia liczb całkowitych bez reszty z zaokrągleniem w dół, if ... then - funkcja warunkowa

Często wzór Zellera jest podawany w formie, w której występuje wartość 2*C zamiast 5*C, która to forma prowadzi jednak przy niektórych latach do wartości N - ujemnych oraz nie sprawdza się dla niektórych dat.

Implementacja w C Funkcja napisana w C na podstawie algorytmu Zellera: char* week={"Niedziela","Poniedzialek","Wtorek","Sroda","Czwartek","Piatek","Sobota"}; int zeller(int d, int m, int y, int gr){ int Y,C,M,N,D; M=1+(9+m)%12; Y=y-(M>10); C=Y/100; D=Y%100; if (gr==1) N=((13*M-1)/5+D+D/4+C/4+5*C+d)%7; else N=((13*M-1)/5+D+D/4+6*C+d+5)%7; return (7+N)%7; } Funkcja zwraca indeks do tablicy „week” (0 dla niedzieli). Parametr „gr” oznacza rodzaj kalendarza: gr=1 dla gregoriańskiego, gr≠1 dla juliańskiego. Inny algorytm (z tym samym efektem) na podstawie analizy tablic zamieszczonych w Małej Encyklopedii Powszechnej PWN z 1959 r. char* week={"Niedziela","Poniedzialek","Wtorek","Sroda","Czwartek","Piatek","Sobota"}; int dow(int d, int m, int y, int gr) { int mon={0,1,1,2,5,6,2,3,4,0,1,4}; int leap; int a,b,c; leap=(gr!=1&&y%4==0||gr==1&&(y%4==0&&y%100!=0||y%400==0)); a=(y%100)%28; b=(gr!=1)*(4+(y%700)/100+2*(a/4)+6*((!leap)*(1+(a%4))+(leap)*((9+m)/12)))%7+ (gr==1)*(2*(1+(y%400)/100+(a/4))+6*((!leap)*(1+(a%4))+(leap)*((9+m)/12)))%7; c=(3*mon[m-1]+d)%7; return (c+6*b)%7; }

Tabele Na podstawie wzoru Zellera można w prosty sposób utworzyć tabele, które mogą one praktycznie obejmować dowolny okres.

Przykładowy kalendarz dla lat 1901-2040:

Opis Przykład dla: 31 I 1901 1. W tabeli Lata - Miesiące szukaj cyfry na przecięciu roku i miesiąca wybranej daty. 1901/I → 1 2. Do odszukanej cyfry dodaj dzień miesiąca otrzymując kod. 1+31=32 3. W tabeli Dni tygodnia szukaj kodu wskazującego dzień tygodnia. 32 → czwartek

Lata Miesiące Pochyła czcionka oznacza lata przestępne I II III IV V VI VII VIII IX X XI XII 1901 1929 1957 1985 2013 1 4 4 0 2 5 0 3 6 1 4 6 1902 1930 1958 1986 2014 2 5 5 1 3 6 1 4 0 2 5 0 1903 1931 1959 1987 2015 3 6 6 2 4 0 2 5 1 3 6 1 1904 1932 1960 1988 2016 4 0 1 4 6 2 4 0 3 5 1 3 1905 1933 1961 1989 2017 6 2 2 5 0 3 5 1 4 6 2 4 1906 1934 1962 1990 2018 0 3 3 6 1 4 6 2 5 0 3 5 1907 1935 1963 1991 2019 1 4 4 0 2 5 0 3 6 1 4 6 1908 1936 1964 1992 2020 2 5 6 2 4 0 2 5 1 3 6 1 1909 1937 1965 1993 2021 4 0 0 3 5 1 3 6 2 4 0 2 1910 1938 1966 1994 2022 5 1 1 4 6 2 4 0 3 5 1 3 1911 1939 1967 1995 2023 6 2 2 5 0 3 5 1 4 6 2 4 1912 1940 1968 1996 2024 0 3 4 0 2 5 0 3 6 1 4 6 1913 1941 1969 1997 2025 2 5 5 1 3 6 1 4 0 2 5 0 1914 1942 1970 1998 2026 3 6 6 2 4 0 2 5 1 3 6 1 1915 1943 1971 1999 2027 4 0 0 3 5 1 3 6 2 4 0 2 1916 1944 1972 2000 2028 5 1 2 5 0 3 5 1 4 6 2 4 1917 1945 1973 20012029 0 3 3 6 1 4 6 2 5 0 3 5 1918 1946 1974 20022030 1 4 4 0 2 5 0 3 6 1 4 6 1919 1947 1975 20032031 2 5 5 1 3 6 1 4 0 2 5 0 1920 1948 1976 20042032 3 6 0 3 5 1 3 6 2 4 0 2 1921 1949 1977 20052033 5 1 1 4 6 2 4 0 3 5 1 3 1922 1950 1978 20062034 6 2 2 5 0 3 5 1 4 6 2 4 1923 1951 1979 20072035 0 3 3 6 1 4 6 2 5 0 3 5 1924 1952 1980 20082036 1 4 5 1 3 6 1 4 0 2 5 0 1925 1953 1981 20092037 3 6 6 2 4 0 2 5 1 3 6 1 1926 1954 1982 20102038 4 0 0 3 5 1 3 6 2 4 0 2 1927 1955 1983 20112039 5 1 1 4 6 2 4 0 3 5 1 3 1928 1956 1984 20122040 6 2 3 6 1 4 6 2 5 0 3 5 Pochyła czcionka oznacza lata przestępne I II III IV V VI VII VIII IX X XI XII

Dni tygodnia Poniedziałek 1 8 15 22 29 36 Wtorek 2 9 16 23 30 37 Środa 3 10 17 24 31 Czwartek 4 11 18 25 32 Piątek 5 12 19 26 33 Sobota 6 13 20 27 34 Niedziela 7 14 21 28 35

Istnieje też inna wersja tabeli, mogąca obejmować wiele stuleci, począwszy od 1 roku n.e. Aby odnaleźć dzień tygodnia dla dowolnej daty, odnajdujemy:

1. W tablicy I a wiek, w tablicy I b rok, na skrzyżowaniu linii odczytamy cyfrę.

2. W tablicy II odczytamy cyfrę na skrzyżowaniu odnalezionej z tablicy I liczby oraz miesiąca. Dla lat przestępnych, oznaczonych kolorem czerwonym, styczeń i luty bierzemy również w ten sposób oznaczone.

3. W tablicy III na skrzyżowaniu liczby z tablicy II oraz daty, odnajdujemy dzień tygodnia poszukiwanej daty.

+ b) Lata000102030405060708091011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889a) Wieki909192939495IJuliańskiGregoriański96979899071417212560123451815560123429182226456012331034560124111519232723456015121620242812345606130123456IIMiesiąceIIIDatyMajSieLutLutMarLisCzeWrzGruKwiLipStyStyPaź12345678910111213141516171819202122232425262728293031123456011NiePonWtoŚroCzwPiąSob234560122PonWtoŚroCzwPiąSobNie345601233WtoŚroCzwPiąSobNiePon456012344ŚroCzwPiąSobNiePonWto560123455CzwPiąSobNiePonWtoŚro601234566PiąSobNiePonWtoŚroCzw012345600SobNiePonWtoŚroCzwPią

Przykład: 18 listopada 2010.

Z tablicy I skrzyżować a) Wieki „20” i b) Lata „10” (tj. 2010) = 6.

Z tablicy II skrzyżować cyfrę 6 i miesiąc „Lis” (listopad) = 2.

Z tablicy III skrzyżować cyfrę 2 z cyfrą 18 tj. dzień = „Czw”, czyli że dzień 18 listopada 2010 był czwartkiem.

Zobacz też Kalendarz

Przypisy

Bibliografia na stronie Dr J R Stockton.

Kategoria:Kalendarze