2. diel - Knižnica DateUtils pre český dátum a čas v PHP
V minulej lekcii, Úvod do knižníc a frameworkov v PHP , sme si vysvetlili, že knižnice sú v PHP nutnosťou a že sa potom združujú do frameworkov.
V dnešnom dieli si vytvoríme svoju prvú knižnicu v PHP - DateUtils. Pred tvorbou každej knižnice si krátko uvedieme prečo ju vlastne vytvárame.
Motivácia
V PHP získavame dátum z databázy často vo formáte yyyy-mm-dd. Používateľovi by sme ho samozrejme chceli vypísať v slovenskom tvare a pomocou PHP funkcií si musíme pamätať formáty ako "jnY G: i: s", ktoré musíme stále dokola hľadať v manuáli. Hoci by dátum teoreticky išlo formátovať priamo v databáze, tak do nej prezentačné logika nepatrí a bol by problém, keby sme túto hodnotu treba neskôr chceli použiť ako ďalší vstup pre nejakú funkciu. A úplne ideálne by sme nášmu užívateľovi dátum chceli vypísať ako "Dnes 15:15" alebo "15.januára".
Pokiaľ vo formulároch nepoužívame nejaký DatePicker z jQuery, príde nám od užívateľa opäť slovensky zapísané dátum a my by sme ho potrebovali naparsovat na databázový formát. Potrebujeme samozrejme tiež overiť, či používateľ zadal zmysluplnú hodnotu a to nielen či zadal správne čísla a medzi nimi bodky, ale aj či nezadal napr. 29. februára v neprestupnom rok.
DateUtils
Za účelom týchto jednoduchých funkcií si vytvoríme triedu DateUtils. Bude sa jednať o pomocnú (Utility) triedu, ktorá nemá žiadny vnútorný stav. Budeme ju tiež často používať na mnohých miestach aplikácie. Z týchto charakteristík usúdime, že jej metódy bude najlepšie urobiť statické.
Ak používate menné priestory, môžete si ju vložiť do namespace Utilities, v ďalších dieloch budeme tvoriť podobné triedy pre prácu s textovými reťazcami a poli.
class DateUtils
{
}
Príprava konštánt
Do triedy si dodajme niekoľko konštánt, kam si uložíme formáty, ktoré budeme pri prevode používať. Prvé 3 sú české dátum s časom, českej dátum a český čas. Určite nemusím pripomínať, že napr. H: i: s sú hodiny: minúty: sekundy, iste si dokážete z PHP manuálu zistiť, čo ktorý symbol znamená.
const DATETIME_FORMAT = 'j.n.Y G:i:s'; const DATE_FORMAT = 'j.n.Y'; const TIME_FORMAT = 'G:i:s'; const DB_DATETIME_FORMAT = 'Y-m-d H:i:s'; const DB_DATE_FORMAT = 'Y-m-d'; const DB_TIME_FORMAT = 'H:i:s';
Kód si riadne okomentujte pomocou phpdoc.
Pomocná pole
Ďalej si vytvoríme 3 pomocná poľa, musí byť samozrejme statická, aby sme k nim mali prístup zo statických metód.
Do prvého poľa si vložíme české názvy mesiacov, do druhého chybové hlášky pre jednotlivé formáty. Do tretieho potom ako sa majú formáty medzi sebou prevádzať, aby bol výsledok vždy v databázovom tvare. Príde mi vhodné v aplikácii pracovať s dátumom a časom práve v tomto formáte, databázy je alfa a omega celej aplikácie, PHP je vlastne len podporný jazyk.
private static $months = array('ledna', 'února', 'března', 'dubna', 'května', 'června', 'července', 'srpna', 'září', 'října', 'listopadu', 'prosince'); private static $errorMessages = array( self::DATE_FORMAT => 'Neplatné datum, zadejte ho prosím ve tvaru dd.mm.rrrr', self::TIME_FORMAT => 'Neplatný čas, zadejte ho prosím ve tvaru hh:mm, můžete dodat i vteřiny', self::DATETIME_FORMAT => 'Neplatné datum nebo čas, zadejte prosím hodnotu ve tvaru dd.mm.rrrr hh:mm, případně vteřiny', ); private static $formatDictionary = array( self::DATE_FORMAT => self::DB_DATE_FORMAT, self::DATETIME_FORMAT => self::DB_DATETIME_FORMAT, self::TIME_FORMAT => self::DB_TIME_FORMAT, );
Formátovanie dátumu a času
Všetka práca s dátumom a časom bude prebiehať pomocou PHP triedy DateTime, ktorá je geniálne navrhnutá a určite by ste ju mali poznať.
Za účelom vytvorenia inštancie DateTime si vytvoríme nasledujúce pomocnú metódu:
public static function getDateTime($date) { if (ctype_digit($date)) $date = '@' . $date; return new DateTime($date); }
Metóda slúži na to, aby bola naša trieda univerzálne a dokázala prípadne formátovať aj dátum z databázy v prípade, že je tu reprezentované ako int (to je počet sekúnd od UNIXové epochy). Či je dátum zadaný ako jedno číslo zistíme funkcií ctype_digit (). V tomto prípade pridáme pred reťazec zavináč. Trieda DateTime zavináč používa práve na označenie UNIX TIMESTAMP a už bude vedieť, ako ho naparsovat. Nutné dodať, že tento formát dátumu je trochu nešikovný a vo svojich aplikáciách sa mu skôr vyhnite, však snažme sa byť univerzálne.
Český formát
Pre formátovanie dáta s časom a samotného dáta z ľubovoľnej podoby do podoby slovenskej (15.1.2014) si vytvoríme dve jednoduché metódy:
public static function formatDate($date) { $dateTime = self::getDateTime($date); return $dateTime->format('d.m.Y'); } public static function formatDateTime($date) { $dateTime = self::getDateTime($date); return $dateTime->format('d.m.Y H:i:s'); }
Metódy môžeme používať v pohľadoch pri výpise dáta z výsledku databázového dopytu. Na tento účel si v budúcnosti vytvoríme triedu FormatHelper, ktorá bude DateUtils využívať.
Ako vždy si logiku vyskúšajme:
require_once('Utility/DateUtils.php'); echo(DateUtils::formatDate(1376906152) . '<br />'); echo(DateUtils::formatDateTime('2014-02-23 10:50') . '<br />'); echo(DateUtils::formatDate('24.2.2014') . '<br />'); echo(DateUtils::formatDate('2014-02-01') . '<br />'); echo(DateUtils::formatDate('2013/02/20') . '<br />');
Výsledok nie je zatiaľ nijako svetoborná, však jednoducho prevedieme akokoľvek zadanej dátum do českej podoby:
V budúcej lekcii, Dokončenie knižnice DateUtils v PHP , si naprogramujeme formátovanie na "pekný formát", ako napr. "Dnes" alebo "15.januára". Triedu dokončíme metódou, ktorá validuje a dekóduje česky zapísané dátum.