IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - Knihovna DateUtils pro český datum a čas v PHP

V minulé lekci, Úvod do knihoven a frameworků v PHP, jsme si vysvětlili, že knihovny jsou v PHP nutností a že se poté sdružují do frameworků.

V dnešním dílu si vytvoříme svou první knihovnu v PHP, půjde o knihovnu DateUtils. Před tvorbou každé knihovny si krátce uvedeme, proč ji vlastně vytváříme.

Motivace

V PHP získáváme datum z databáze často ve formátu yyyy-mm-dd. Uživateli bychom ho samozřejmě chtěli vypsat v českém tvaru a pomocí PHP funkcí si musíme pamatovat formáty jako j.n.Y G:i:s, které musíme stále dokola hledat v manuálu. Ačkoli by datum teoreticky šlo formátovat přímo v databázi, tak do ní prezentační logika nepatří a byl by problém, kdybychom tuto hodnotu třeba později chtěli použít jako další vstup pro nějakou funkci. A úplně ideálně bychom našemu uživateli datum chtěli vypsat jako Dnes 15:15 nebo 15.ledna.

Pokud ve formulářích nepoužíváme nějaký DatePicker s pomocí knihovny jQuery, přijde nám od uživatele opět česky zapsané datum a my bychom ho potřebovali naparsovat na databázový formát. Potřebujeme samozřejmě také ověřit, zda uživatel zadal smysluplnou hodnotu a to nejen jestli zadal správně čísla a mezi nimi tečky, ale i jestli nezadal např. 29.února v nepřestupný rok.

DateUtils

Za účelem těchto jednoduchých funkcí si vytvoříme třídu DateUtils. Bude se jednat o pomocnou (Utility) třídu, která nemá žádný vnitřní stav. Budeme ji také často používat na mnoha místech aplikace. Z těchto charakteristik usoudíme, že její metody bude nejlepší udělat statické.

Pokud používáte jmenné prostory, můžete si ji vložit do namespace Utilities, v dalších dílech budeme tvořit podobné třídy pro práci s textovými řetězci a poli:

class DateUtils
{

}

Příprava konstant

Do třídy si dodejme několik konstant, kam si uložíme formáty, které budeme při převodu používat. První 3 jsou české datum s časem, české datum a český čas. Určitě nemusím připomínat, že např. H:i:s jsou hodiny:minuty:sekundy, jistě si dokážete z PHP manuálu zjistit, co který 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 řádně okomentujte pomocí PhpDoc.

Pomocná pole

Dále si vytvoříme 3 pomocná pole, musí být samozřejmě statická, abychom k nim měli přístup ze statických metod:

private static array $months = array('ledna', 'února', 'března', 'dubna', 'května', 'června', 'července', 'srpna', 'září', 'října', 'listopadu', 'prosince');

private static array $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 array $formatDictionary = array(
    self::DATE_FORMAT => self::DB_DATE_FORMAT,
    self::DATETIME_FORMAT => self::DB_DATETIME_FORMAT,
    self::TIME_FORMAT => self::DB_TIME_FORMAT,
);

Do prvního pole si vložíme české názvy měsíců, do druhého chybové hlášky pro jednotlivé formáty. Do třetího potom jak se mají formáty mezi sebou převádět, aby byl výsledek vždy v databázovém tvaru. Přijde mi vhodné v aplikaci pracovat s datem a časem právě v tomto formátu, databáze je alfa a omega celé aplikace, PHP je vlastně jen podpůrný jazyk.

Formátování data a času

Veškerá práce s datem a časem bude probíhat pomocí PHP třídy DateTime, která je geniálně navržená a určitě byste ji měli znát.

Za účelem vytvoření instance DateTime si vytvoříme následující pomocnou metodu getDateTime():

public static function getDateTime(string $date): DateTime
{
    if (ctype_digit($date))
        $date = '@' . $date;
    return new DateTime($date);
}

Metoda slouží k tomu, aby byla naše třída univerzální a dokázala případně formátovat i datum z databáze v případě, že je zde reprezentované jako datový typ int (to je počet sekund od UNIXové epochy). Zda je datum zadáno jako jedno číslo zjistíme funkcí ctype_digit() (zda je text obsahující pouze číslice). Ve starších verzích PHP, kde nemůžeme určit datové typy v metodách, bychom použili navíc ještě funkci is_int() (zda je přímo již číslo):

public static function getDateTime($date)
{
    if (ctype_digit($date) || is_int($date))
        $date = '@' . $date;
    return new DateTime($date);
}

My ale víme, že máme k dispozici pouze datový typ string, čili číslo tam nikdy nebude, proto můžeme funkci is_int() vynechat.

V případě platnosti podmínky přidáme před řetězec zavináč @. Třída DateTime zavináč používá právě k označení UNIX timestampu a už bude vědět, jak ho naparsovat. Nutno dodat, že tento formát data je poněkud nešikovný a ve svých aplikacích se mu spíše vyhněte, nicméně snažme se být univerzální.

Český formát

Pro formátování data s časem a samotného data z libovolné podoby do podoby české (15.1.2014) si vytvoříme dvě jednoduché metody:

public static function formatDate(string $date): string
{
    $dateTime = self::getDateTime($date);
    return $dateTime->format('d.m.Y');
}

public static function formatDateTime(string $date): string
{
    $dateTime = self::getDateTime($date);
    return $dateTime->format('d.m.Y H:i:s');
}

Metody můžeme používat v pohledech při výpisu data z výsledku databázového dotazu. Za tímto účelem si v budoucnu vytvoříme třídu FormatHelper, která bude knihovnu DateUtils využívat.

Jako vždy si logiku vyzkoušejme:

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ýsledek není zatím nijak světoborný, nicméně jednoduše převedeme jakkoli zadané datum do české podoby:

Formát data a času
localhost

V příští lekci, Dokončení knihovny DateUtils v PHP, si naprogramujeme formátování na "hezký formát", jako např. "Dnes" nebo "15.ledna". Třídu dokončíme metodou, která validuje a parsuje česky zapsané datum.


 

Předchozí článek
Úvod do knihoven a frameworků v PHP
Všechny články v sekci
Knihovny pro PHP
Přeskočit článek
(nedoporučujeme)
Dokončení knihovny DateUtils v PHP
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
31 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity