Kalendarz wiecznyKalendarz 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 tygodniaMetoda konwergencji ZelleraKalendarz 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[1]. Uproszczony wzór KeithaAlgorytm Zellera został uproszczony i opublikowany w 1990 roku przez matematyka Mike'a Keitha do postaci[2][1]:
Zaletą wzoru Mike'a Keitha jest możliwość zapisania go w języku programowania C w jednej linii liczącej raptem 45 znaków[3], 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ówNależ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[4][5]. 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[6]. 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[7]. Przykładowe implementacjePoniżej podane są przykładowe implementacje w podstawowych językach programowania. Implementacja w PascaluZapis 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[12]=('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;
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 CFunkcja napisana w C na podstawie algorytmu Zellera: char* week[7]={"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:
Inny algorytm (z tym samym efektem) na podstawie analizy tablic zamieszczonych w Małej Encyklopedii Powszechnej PWN z 1959 r. char* week[7]={"Niedziela","Poniedzialek","Wtorek","Sroda","Czwartek","Piatek","Sobota"};
int dow(int d, int m, int y, int gr)
{
int mon[12]={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;
}
TabeleNa podstawie wzoru Zellera można w prosty sposób utworzyć tabele, które mogą one praktycznie obejmować dowolny okres[potrzebny przypis]. Przykładowy kalendarz dla lat 1901-2040:
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.
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żPrzypisy
Bibliografia
|