Wieczny kalendarz
Z Wikipedii
Kalendarz wieczny - tabela lub wzór pozwalająca w prosty sposób odnaleźć określony dzień tygodnia w kalendarzu gregoriańskim dla każdej daty w postaci dzień miesiąca, miesiąc, rok. Przy pomocy wiecznego kalendarza nie ma możliwości obliczenia np: roku na podstawie daty w postaci: dzień tygodnia, dzień miesiąca - gdyż dni tygodnia dla danego dnia miesiąca powtarzają się acyklicznie w kalendarzu gregoriańskim.
Spis treści |
[edytuj] Uniwersalny wzór Zellera dla lat 1 - 9999 n.e.
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.
Pełen zapis w języku Pascal algorytmu obliczania dnia tygodnia w kalendarzu Gregoriańskim, opublikowanego w Acta Mathematica, vol.9 (1886-7), pp.131-6,:
- 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 + 1) mod 7 ; ?
- N := ((13*M-1) div 5 + D + D div 4 + C div 4 + 5*C) mod 7 ; ?
- gdzie Month = trzyliterowa nazwa miesiąca stosowana w języku Pascal, 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.
Algorytm Zellera został uproszczony przez matematyka, Mikea Keitha do postaci:
- dzień tygodnia = ([23m/9] + d + 4 + y + [z/4] - [z/100] + [z/400] - 2 (if m >= 3) ) mod 7
- gdzie
- [ ] oznacza dzielenie bez reszty z zaokrągleniem w dół
- mod - funkcja modulo
- m - numer miesiąca (od stycznia = 1 do grudnia = 12)
- d - numer dnia miesiąca
- z = y - 1 jeśli m < 3,
- z = y w pozostałych przypadkach
Zaletą wzoru Mike'a Keitha jest możliwość zapisania go w języku programowania C w jednej linii liczącej raptem 45 znaków:
- (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7
która to linia kodu generuje wartość D kodującą dzień tygodnia od niedzieli (0) do soboty (6)
Wzór ten został opublikowany w Journal of Recreational Mathematics, Vol. 22, No. 4, 1990, p. 280.
[edytuj] Implementacja w C
char* week[7]={"Niedziela","Poniedzialek","Wtorek","Sroda","Czwartek","Piatek","Sobota"}; int dow(int m, int d, int y, int s) { int mon[12]={0,1,1,2,5,6,2,3,4,0,1,4}; int leap; int a,b,c; leap=(s==0&&y%4==0||s!=0&&(y%4==0&&y%100!=0||y%400==0)); a=(y%100)%28; b=(s==0)*(4+(y%700)/100+2*(a/4)+6*((!leap)*(1+(a%4))+(leap)*((9+m)/12)))%7+ (s!=0)*(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; }
Funkcja zwraca indeks do tablicy "week". Parametr s oznacza styl
- s==0 dla stylu juliańskiego
- s!=0 dla stylu gregoriańskiego
[edytuj] Kalendarze stuletnie
Na podstawie wzoru Zellera można w prosty sposób utworzyć tabele, które bywają nazywane kalendarzami stuletnimi choć mogą one praktycznie obejmować dowolny okres. Przykładowy "kalendarz stuletni" (a właściwie stuczterdziestoletni) dla lat 1901-2040:
Opis | Przykład dla: 31 VIII 1984 | |
1. W tabeli Lata znajdź liczbę na przecięciu roku i miesiąca wybranej daty | 1984/VIII → 2 | |
2. Do odszukanej liczby dodaj dzień miesiąca | 2+31=33 | |
3. W tabeli Kod dnia tygodnia znajdź odpowiadający wynikowi dzień tygodnia | 33 → piątek |
Lata 1901-2040 | Miesiące | ||||||||||||||||
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 | 2001 | 2029 | 0 | 3 | 3 | 6 | 1 | 4 | 6 | 2 | 5 | 0 | 3 | 5 | |
1918 | 1946 | 1974 | 2002 | 2030 | 1 | 4 | 4 | 0 | 2 | 5 | 0 | 3 | 6 | 1 | 4 | 6 | |
1919 | 1947 | 1975 | 2003 | 2031 | 2 | 5 | 5 | 1 | 3 | 6 | 1 | 4 | 0 | 2 | 5 | 0 | |
1920 | 1948 | 1976 | 2004 | 2032 | 3 | 6 | 0 | 3 | 5 | 1 | 3 | 6 | 2 | 4 | 0 | 2 | |
1921 | 1949 | 1977 | 2005 | 2033 | 5 | 1 | 1 | 4 | 6 | 2 | 4 | 0 | 3 | 5 | 1 | 3 | |
1922 | 1950 | 1978 | 2006 | 2034 | 6 | 2 | 2 | 5 | 0 | 3 | 5 | 1 | 4 | 6 | 2 | 4 | |
1923 | 1951 | 1979 | 2007 | 2035 | 0 | 3 | 3 | 6 | 1 | 4 | 6 | 2 | 5 | 0 | 3 | 5 | |
1924 | 1952 | 1980 | 2008 | 2036 | 1 | 4 | 5 | 2 | 3 | 6 | 1 | 4 | 0 | 2 | 5 | 0 | |
1925 | 1953 | 1981 | 2009 | 2037 | 3 | 6 | 6 | 2 | 4 | 0 | 2 | 5 | 1 | 3 | 6 | 1 | |
1926 | 1954 | 1982 | 2010 | 2038 | 4 | 0 | 0 | 3 | 5 | 1 | 3 | 6 | 2 | 4 | 0 | 2 | |
1927 | 1955 | 1983 | 2011 | 2039 | 5 | 1 | 1 | 4 | 6 | 2 | 4 | 0 | 3 | 5 | 1 | 3 | |
1928 | 1956 | 1984 | 2012 | 2040 | 6 | 2 | 3 | 6 | 1 | 4 | 6 | 2 | 5 | 0 | 3 | 5 | |
Pochyłą czcionką oznaczono lata przestępne | I | II | III | IV | V | VI | VII | VIII | IX | X | XI | XII |
Kod dnia 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 |
[edytuj] Bibliografia
- Omówienie wzoru Zellera na stronie Dr J R Stockton.
- Algorytm Mike'a Kitha - omówiony na jego stronie osobistej
- zbiór algorytmów dotyczących kalendarza
[edytuj] Linki zewnętrzne
Kalendarze |
księżycowy – księżycowo-słoneczny - słoneczny |
egipski – starogrecki – rzymski - słowiański - bizantyjski |
babiloński – Majów – aztecki |
juliański – gregoriański - wieczny |
koptyjski – muzułmański – żydowski |
hinduski – chiński - japoński |
francuski rewolucyjny – radziecki |
"World Calendar" - północnokoreański |