Algoritmus pro výpočet dne v týdnu

Technology
12 hours ago
8
4
2
Avatar
Author
Albert Flores

Algoritmus pro výpočet dne v týdnu neboli Zellerův algoritmus je postup, jak ze zadaného data (např. „13. února 2011“) zjistit, o jaký den v týdnu se jedná (výstupem je tedy „neděle“). Pro tento účel je také možno použít takzvaný věčný kalendář, což je tabulka, z níž lze odečíst, na který den týdne datum připadá, avšak pro počítač je jednodušší přímý výpočet pomocí vhodného algoritmu. K tomuto účelu lze použít právě Zellerův algoritmus, jehož autorem je německý matematik devatenáctého století Christian Zeller. Jeho postup vychází z čísla dne, měsíce, roku a století a počítá z těchto vstupních údajů na základě vzorce číslo, jež dává při dělení sedmi stejný zbytek jako pořadové číslo daného dne v týdnu, takže zbytku 1 odpovídá pondělí, zbytku 2 úterý až zbytku 7, tedy 0, neděle.

Zellerův algoritmus

Vzorce

Pro gregoriánský kalendář má Zellerův algoritmus tvar:

:h = \left(q + \left\lfloor\frac{13(m+1)}{5}\right\rfloor + K + \left\lfloor\frac{K}{4}\right\rfloor + \left\lfloor\frac{J}{4}\right\rfloor - 2J\right) \mod 7,

Pro juliánský kalendář má Zellerův algoritmus tvar:

:h = \left(q + \left\lfloor\frac{13(m+1)}{5}\right\rfloor + K + \left\lfloor\frac{K}{4}\right\rfloor + 5 - J\right) \mod 7,

kde * \lfloor \rfloor značí celou část čísla (podíl dělení se zbytkem) a mod zbytek po dělení * h je den v týdnu: 0 = sobota, 1 = neděle, . , 6 = pátek * q je den v měsíci * m je měsíc: 13* = leden, 14* = únor, 3 = březen, 4 = duben, . +more, 12 = prosinec * K je rok 0-99 století (rok\mod 100), pro leden a únor o jednu nižší (počítají se do předchozího roku)* * J je druhá část letopočtu - číslo tvořené prvními dvěma číslicemi (\lfloor rok/100 \rfloor), např. pro 2017 je J = 20.

Poznámka: *V tomto algoritmu datum D. M. +moreRRRR odpovídá proměnným q. m. JK, ale leden a únor jsou kvůli přestupným rokům počítány jako 13. a 14. měsíc předchozího roku. Například datum 2. února 2010 algoritmus počítá jako 2. den 14. měsíce roku 2009.

Pro převod na den v týdnu začínající pondělím d (1 = Pondělí až 7 = Neděle) použijeme: :d = ((h + 5) \mod 7) + 1

Implementace do programu

Vzorce jsou založeny na matematické definici a definicí modulo tedy zbytek po dělení, což znamená, že -2 mod 7 se rovná +5. Avšak způsob, jakým je ve většině počítačových jazycích definován zbytek po dělení, tomuto neodpovídá, takže -2 mod 7 vrátí výsledek -2. +more Z tohoto důvodu musí být Zellerovy vzorce upraveny a zajistit tak kladné čitatele. Nejjednodušší způsob, jak to udělat, je nahradit - 2 J o + 5 - J a J o + 6 J. Dostaneme tedy vzorce:.

Pro Gregoriánský kalendář má tvar:

:h = \left(q + \left\lfloor\frac{13(m+1)}{5}\right\rfloor + K + \left\lfloor\frac{K}{4}\right\rfloor + \left\lfloor\frac{J}{4}\right\rfloor + 5J\right) \mod 7,

a pro Juliánský kalendář má tvar:

:h = \left(q + \left\lfloor\frac{13(m+1)}{5}\right\rfloor + K + \left\lfloor\frac{K}{4}\right\rfloor + 5 + 6J\right) \mod 7,

Je snadno vidět, že v daném roce 1. března (pokud je to sobota, tak 2. března) je vhodné k otestování data. A to tak, že v daném století je nejvhodnější k testu rok dělitelný 100.

Zeller používá desetinné počty, a nachází tak vhodné J a K, které reprezentují daný rok. Ale když používáme počítač, je jednodušší použít modifikované Y, které je Y - 1 během ledna a února:

Pro Gregoriánský kalendář má tvar:

:h = \left(q + \left\lfloor\frac{(m+1)26}{10}\right\rfloor + Y + \left\lfloor\frac{Y}{4}\right\rfloor + 6\left\lfloor\frac{Y}{100}\right\rfloor + \left\lfloor\frac{Y}{400}\right\rfloor\right) \mod 7,

a pro Juliánský kalendář má tvar:

:h = \left(q + \left\lfloor\frac{(m+1)26}{10}\right\rfloor + Y + \left\lfloor\frac{Y}{4}\right\rfloor + 5\right) \mod 7,

Analýza

Tyto vzorce jsou založeny na pozorování, že den v týdnu, postupuje předvídatelným způsobem, založené na každé hlavě po tomto dni. Každý termín ve vzorci je použit pro výpočet vyrovnání potřebné pro získání správného dne v týdnu.

Pro gregoriánský kalendář lze různé části tohoto vzorce tedy chápat takto: * q představuje průběh dne v týdnu na základě dne v měsíci, od té doby má každý následující den za následek další posun jeden den v týdnu. * K představuje průběh dne v týdnu na základě roku. +more Za předpokladu, že každý rok má 365 dnů, stejné datum v každém následujícím roce budou dány hodnotou 365\mod 7 = 1. * Protože je 366 dnů v přestupném roce, musí to být ošetřeno tím, že se přidá další den na den v týdnu. Tím dosáhneme toho, že \left\lfloor\frac{K}{4}\right\rfloor je přičteno k vyrovnání. Tento termín se vypočítá jako celočíselný výsledek. Jakýkoliv zbytek je vyloučen. * Pomocí podobné logiky, můžeme průběh dne v týdnu pro každé století vypočítát tím, že pozorujeme, že existuje 36524 dní v běžném století a 36525 dní v každém století dělitelném 400. Tedy 36525\mod 7 = 6 a 36524\mod 7 = 5, výraz :\left\lfloor\frac{J}{4}\right\rfloor - 2J odpovídá za to (opět pomocí celočíselné dělení a odkládání jakékoliv frakčního zbytku). To Aby se zabránilo záporným číslům, může tento termín nahradit :\left\lfloor\frac{J}{4}\right\rfloor + 5J s odpovídajícími výsledky.

* Termín lze vysvětlit následovně: \left\lfloor\frac{(m+1)26}{10}\right\rfloor. Zeller vypozoroval, že každý rok začíná 1. +more března, den v týdnu každého následujícího měsíce dostáváme násobením konstantní hodnotou a neuvažujeme žádný frakční zbytek.

Celková funkce \mod 7, normalizuje výsledek v rozmezí od 0 do 6, který určuje správný den v týdnu pro datum.

Důvodem, že se vzorec liší od juliánského kalendáře je, že tento kalendář nemá zvláštní pravidlo pro přestupná století a jeho posun je na rozdíl od gregoriánského kalendáře dán pevným počtem dnů v každém století.

Vzhledem k tomu, že gregoriánský kalendář byl přijat v různých obdobích v různých regionech světa. Místo události, k níž došlo během tohoto přechodného období, je významné pro určení správného dne v týdnu.

Vzorce lze použít neomezeně, ale musíme dbát na to, že pro letopočet před rokem 0. je třeba přidat dostatečný násobek 400 pro Gregoriánský kalendář nebo 28 let pro Juliánský kalendář.

5 min read
Share this post:
Like it 8

Leave a Comment

Please, enter your name.
Please, provide a valid email address.
Please, enter your comment.
Enjoy this post? Join Cesko.wiki
Don’t forget to share it
Top