Článek v rubrikách:

»PHP
»MySQL

Jak na svátky v PHP a MySQL?

Práce se svátky jednou potká snad každého programátora, na netu je tisíce návodů jak na to, ale na každém mi něco vadí. Kam ukládat databázi svátků, v jakém formátu a jak k nim přistupovat? Jak je zpracovávat? Co třeba všichni uživatelé kteří mají dnes svátek?


Zdrojový kód ke stažení tabulka-svatky.sql

Dosud jsem se této úloze vyhýbal nebo použil jakýkoli dostupný materiál z netu search svátky php.

Bohužel mne neuspokojil žádný nabízený návod, od způsobu uložení až po řešení přestupného roku apod.

1. Přestupný rok

Většina návodů to řeší příliš složitě různými přepočty, ale proč neukládat data ve formátu day(24.12), name(Adam), day(29.02), name (Horymír). Když je přestupný rok přistupujeme k datu 29.02 ne ke dni 61, kde je nutné přepočítat jestli je to 60 nebo 62 tento rok, no a když není přestupný rok, tak se ke dni 29.02 ani nedostaneme.

2. Více svátků v jeden den, stejný svátek ve více dní

Další věcí co mi vadí, je že tyto návody nerespektují dny jako 24.12 Adam a Eva, což z hlediska zpracování je nepřijatelné. Nebo jiný problém co svátek 22.02 Petr a jiný svátek 29.06 Petr a Pavel, Petr má totiž svátek 2x v roce. Tedy je potřeba ukládat data tak, aby obsahovali jednotný identifikátor svátku (ne Petr a Pavel) a aby bylo možné zapsat více svátků na ten samý den a více jmen na rozdílné dny.

Celá vygenerovaná databáze v kódování UTF-8, by pak měla vypadat nějak takto tabulka-svatku.sql. Ještě upozorňuji, že v ni nenajdete státní svátky, nový rok apod. pouze jména (jmeniny).

3. Ukládat do mysql nebo do pole (Array)

Jsem pro, aby byla použita databáze. Umožňuje to práci se svátky přímo v databázi bez aplikační vrstvy a hlavně umožní mi to například následující obrat:

  1. SELECT nd.*, u.* FROM users u JOIN namedays nd ON (u.name LIKE CONCAT(nd.name, ' %') AND nd.day='09.08');

Jedním dotazem jen na základě dne získáme všechny uživatele, kdo mají ten den svátek. Můžeme také jedním dotazem získat seznam a počty svátků všech uživatelů. Pokrývá to i zmíněné případy jako Adam a Eva apod.

komentáře

RSS Komentáře k článku RSS Komentáře   Add to Google
27.01.2009 20:34 | Anonym (Horst) | Menší připomínky

Podobný problém, no on to snad ani není problém, spíš taková hloupůstka, jež potěší, jsem řešil kdysi dávno pradávno. Takže pokud mohu, něco bych připsal. Samozřejmě, že je to to nejjednodušší řešení, řešení, jež obchází problémy s obtížně počitatelným kalendářem – mám na mysli přestupné roky a podobně. Nevím, pro jaké účely má tahle databáze sloužit, ale mohl by se šiknout jednoduchý, velmi jednoduchý, způsob jak získat svátky či jmeniny relativně, tedy dnes, zítra, předevčírem a podobně. Z popisovaného řešení to není zcela zjevné. Z podobného důvodu a taky z důvodu návrhu databází bych přece jen oddělil den a měsíc, dal bych je do samostatných atributů. To už ale asi hnidopišství, uznávám, jen by to bylo databázově čistší a mám zkušenost, samozřejmou, že čistší řešení obvykle znamená lepší výsledky. A nakonec – není důležité, zda mám či nemám rád MySQL (nemám), ale jsem přesvědčen o tom, že databázové řešení by mělo být nazváno databázovým – MySQL není synonymem pro databázový server. Popisovaný „problém“ by vyřešila kterákoliv ze známých databází. Ale to je samozřejmě to nejmenší.

27.01.2009 23:04 | Administrátor | Re: Menší připomínky
  1. ooddělení dne a měsíce – proč ne, souhlasím, řešení jsem psal dnes, cca deset minut před napsáním toho článku a to jsem ještě převáděl databázi ze seznamu očíslovaným pouze pořadovým číslem, mne to vyhovuje, pokud někdo shledá užitečnost, určitě je to dobrá připomínka, hlavně když to není postaveno na pořadovém čísle
  2. mysql – snadná odpověď, tento web začal vznikat ve chvíli, když jsem byl nespokojen s nabídkou článků na určitá klíčová slova, resp. cílem je rozšířit dostupné informační zdroje, ke kterým bude snadné se rychle dostat a hlavně, které jsou česky, a jací uživatelé nejvíce hledají svátky v souvislosti s programováním? tedy klíčová slova php a svátky, mysql a svátky, proto je to tak postavené a o tom mimo jiné je tento web
28.01.2009 21:09 | Anonym (Horst) | opravdu naposledy :)

Ale opravdu, kvůli takové maličkosti se nebudeme zatěžovat :) Ona ta pořadová čísla mají svůj smysl, smysl jenž spočívá právě ve snadném získání pořadí svátků pro účel jednoduchého zjištění svátku předešlého, následujícího a tak podobně, jak jsem již psal. Jistě by se to dalo napodobit právě oddělením měsíce a dne a pak správným tříděním, jen je to tak výrazně jednodušší – jako pomocný, nikoliv ovšem klíčový atribut. Oddělení měsíce a dne pak řeší další věci, např. výpis svátků pro daný měsíc a podobně. Jistě se to dá řešit pomocí řetězcových operací, ale – není to tak hezké :) Děkuji za čas strávený čtením a reakcí, už jej o Vás nebudu okrádat :)

29.01.2009 11:21 | Administrátor | Re: opravdu naposledy :)

v pohodě proto ten blog píšu, dobrá máte pravdu já řešil jen aktuální problém, jestli naopak vy máte čas se tomu věnovat vygenerujte tabulku podle Vás, zvěřejním ji zde a dám odkaz na Vaše stránky

17.10.2010 10:18 | Anonym (petr) | tip

díky, tabulka svátků ke stažení mi ušetřila spoustu práce!

08.03.2011 12:16 | Anonym (kubik256) | Upravená table

Dekuji za tabulku, byla velice užitečná.

Jinak k tomu co jste tu řešili s oddělením měsíce a dne – já sem si dovolil ji dle toho upravit a tady je ke stažení výsledek: http://kubik256.comze.com/…a-svatky.sql

Samozřejmě sem jí nepřepisoval ručně, akorat sem jí projel přes makro. Snad se bude hodit ;)

22.03.2011 17:51 | Anonym (Vizor) | Komplexnejsi tabulka

Cau, taky diky za tabulku. Udelal jsem v ni nejake upravy, tak ji prikladam pro ostatni: http://www.4shared.com/…olidays.html?…

Pridal jsem do ni statni svatky a vyznamne dny (velikonoce si musite dopocitat sami). Datum jsem zmenil na datetime. Myslim, ze s tim se diky built-in SQL funkcim pracuje nejlepe. Pridal jsem sloupec type, ktery urcuje, co za den to je (je to string, abych zachoval data v jedny tabulce, myslim, ze neni slozite to popripadne oddelit). nameDay jsou jmeniny, publicHoliday jsou svatky, kdy se nepracuje a nationalDay jsou vyznamne statni dny. id jsem pridal pro poradek. Pokud by nekdo neco z toho nechtel nebo neco chtel jinak, myslim ze jde mnoho docilit diky jednoduchym dotazum nebo upravam (napriklad odstranit sloupecek id apod.).

04.07.2011 17:16 | Anonym (Jack) | RE: komplexnější tabulka

No tak tak komplexnější tabulka je již nepřístupná. Pokud ni někdo obnoví, zlobit se nebudu :-)

Jméno
Název
Text
Lze používat Texy! syntax. Příklad syntaxe: "text odkazu":odkaz, **tučně**, *kurzíva*, `code`. PHP kód uzavírejte do <?php ... ?> a JavaScript do <script> ... </script>