PHP funkce date(), datum a čas

Funkce date() slouží pro práci s datem a časem. Používá ve dvou případech:

  • Zjištění aktuálního stavu, tedy aktuálního data, času, … a vypsání v určitém formátu,
  • Převod konkrétního data do jiného formátu (například číslo měsíce na název, tvar zápisu roků, 12 a 24 soustava hodin, …).

Ukázka

Já jsem speciální stránka. Vím, že právě je
<?php
    echo date("H:i"); // Hodina:minuta
?>

POZOR: PHP nevypisuje Váš čas, ale čas na serveru. Proto se vám může stát, že se zobrazí jiný čas, než má nastavený Váš počítač.

Syntaxe zadávání

Funkce se volá běžným způsobem a jednotlivé požadavky se zadávají jako argumenty funkce.

echo date("formátovací značky", atribut konkrétního času);

Formátovací značky uvádějí, v jakém formátu se datum vypíše. Mezi značky můžou být mezery, tečky, dvojtečky, pomlčky, spojovníky a jiné znaky, které nejsou sami formátovací značkou (pokud chcete použít formátovací znak, musíte jej escapovat). Přehled jednotlivých značek je níže.

Druhý (nepovinný) atribut uvádí ručně zadaný datum nebo čas, který bude převeden a vypsán ve formátu podle prvního parametru. Musí být zadán jako timestamp (lze získat přes formátovací značku „U“).

Příklad:

echo date("d. m. Y", 1405856605); // vypíše 20. 07. 2014

Tabulka povolených formátovacích značek

Znak Popis
Y Rok jako čtyřčíslí (např. 1998)
y Rok jako dvojčíslí (např. 98)
M Anglická zkratka jména měsíce (např. Jan)
m Číslo měsíce (01–12)
F Anglické jméno měsíce (např. January)
D Anglická zkratka dne v týdnu (např. Fri)
l Anglické jméno dne v týdnu (např. Friday)
w Číslo dne v týdnu (1–7)
d Číslo dne v měsíci (01–31)
j Číslo dne v měsíci (1–31)
z Číslo dne v roce (001–365)
H Hodina (00–23)
h Hodina (01–12)
i Minuta (00–59)
s Sekunda (00–59)
U Timestamp: Počet sekund od začátku času (od 1. ledna 1970)
S Anglická koncovka pořadového čísla dne v měsíci
A Indikátor dopoledne/odpoledne (AM/PM)
a Indikátor dopoledne/odpoledne (am/pm)

Získání českých názvů dnů a měsíců

V PHP nelze běžným způsobem získat české názvy dnů a měsíců, proto si takové hodnoty musíme napsat sami. Nejlepší způsob je uložení položek do pole a jejich získání za pomoci volání indexu.

$mesice = [
            1 => 'leden', 'únor', 'březen', 'duben', 'květen',
            'červen', 'červenec', 'srpen', 'září', 'říjen',
            'listopad', 'prosinec'
          ];

$dny = ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'];

Tato ukázka je zjednodušený příklad od Jakuba Vrány ze článku České názvy měsíců a dnů v týdnu.

Přeložení data z angličtiny do češtiny

Často máme datum třeba ve formátu Friday, 13 September a chceme jej přeložit do češtiny, ale jak na to? Nejlepší způsob je zavolat nějakou funkci, třeba datumcesky(), které předáme anglické datum a ona jej přeloží.

function datumcesky($date) {
    $men = [
            "January", "February", "March", "April", "May",
            "June", "July", "August", "September", "October",
            "November", "December"
           ];

    $mcz = [
            "ledna", "února", "března", "dubna", "května",
            "června", "července", "srpna", "září", "října",
            "listopadu", "prosince"
           ];

    $date = str_replace($men, $mcz, $date);

    $den = [
            "Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday"
           ];

    $dcz = [
            "Pondělí", "Úterý", "Středa", "Čtvrtek",
            "Pátek", "Sobota", "Neděle"
           ];

    $date = str_replace($den, $dcz, $date);

    return $date;
}

Příklad použití:

echo datumcesky('Friday, 13 September'); // Pátek, 13 prosince

Tato funkce pro překlad rozhodně není ideální, protože pouze nahrazuje anglická slova za česká, nicméně pro mnoho nasazení může stačit. Pro pokročilejší překlad je potřeba vždy garantovat přesnou syntaxi, na základě které se bude překládat vždy do jednotného stylu, třeba: pátek, 13. prosince.

Ukázka pochází od Fisira ze článku České názvy měsíců a dní v PHP.

Posuny v čase / převod formátování a validace data

Často potřebujeme přeskočit o relativní čas (třeba o + 5 dnů), nebo z textového vstupu uživatele vytáhnout datum tak, aby byl validní. K tomu slouží funkce StrToTime, která povoluje následující syntaxi:

echo strtotime("now");
echo strtotime("10 September 2000");
echo strtotime("+1 day");
echo strtotime("+1 week");
echo strtotime("+1 week 2 days 4 hours 2 seconds");
echo strtotime("next Thursday");
echo strtotime("last Monday");

Výstup funkce je timestamp (univerzální čas) zadaného času.

Obecně doporučuji tuto funkci nasadit na všechny formuláře, kde nějakým způsobem pracujeme s časem od uživatele. Určitě není dobré uživatele nutit psát datum v nějakém konkrétním formátu, ale vždy si takový formát vytvořit automaticky, ať si uživatel může psát, co chce. Často totiž text například odněkud vykopíruje a ruční přeformátování je příliš mnoho práce, když to lze dělat automaticky.

Počet sekund od začátku času

Od 1. ledna 1970 se každou sekundu přičte jednička a tím získáme obrovské celé číslo, které uvádí čas, který od té doby uběhl. Toto se hodí zejména pro jednoduché počítání rozdílů časů. Je to poměrně spolehlivé řešení, ale má i své rizika (problém roku 2038).

Obecné vlastnosti tohoto zápisu:

  • Je to celé číslo, takže se s tím dobře pracuje,
  • Je v desítkové soustavě, takže je i pro lidi dobře čitelné (akorát nelze rychle poznat, o jaký přesný čas jde),
  • Nelze jím vyjádřit období před 1.1.1970, protože nemůže být záporné (některé nové verze algoritmu implementují i záporné časy, ale nelze se na to vždy spolehnout),
  • V roce 2038 přestane fungovat na 32 bitových počítačích a způsobí pád programu (kvůli přetečení zásobníku a maximální velikosti integeru).

Problém roku 2038

Načítám…

Nad tímto textem se zobrazuje aktuální hodnota času, která se každou sekundu zvětší o +1. Aktuální hodnota se načítá javascriptem, proto nemusí být vždy přesná (udává systémový čas vašeho počítače).

Počítače ukládají celá čísla v binární podobě, a pokud jde o integer, tak má často 32 bitů (32 jedniček a nul). Nejvyšším možným 32-bitovým číslem je: 011 111 111 111 111 111 111 111 111 111 11.

Pokud však každou sekundu přičteme k této konstantě +1, tak jednoho dne takové číslo získáme (bude to 19. ledna 2038 v 03:14:07). Při pokusu o přičtení další jedničky již ale nebude stačit bitový rozsah (číslo by bylo větší, než je možné uložit na 32 bitů), tak dojde k přetečení zásobníku, tj. na začátek čísla se doplní jednička, což v binární podobě znamená záporné číslo, (takže to nejspíše způsobí pád programu), dostaneme se někam na rok 1901 (uff!).

Moderní systémy tento problém řeší rozšířením integeru pro uložení data z 32 bitů na 64 bitů, což by mělo stačit na několik tisíc let.

Různé časové zóny

PHP je inteligentní, proto se snaží vždy použít aktuální nejlepší časovou zónu, kde je umístěn server. Občas se však může stát, že je zóna nesprávně určena, nebo programujeme globální aplikaci, kam přistupují uživatelé z celého světa a proto potřebujeme časovou zónu ručně změnit.

To se dá udělat globálně pro celý PHP script zavoláním funkce:

date_default_timezone_set('UTC');

Občas se lze setkat i s tímto řešením (detekce toho, že má server jinou časovou zónu, než UTC):

$defaultTimeZone = 'UTC';

if (date_default_timezone_get() != $defaultTimeZone) {
    date_default_timezone_set($defaultTimeZone);
}

Změna data a času

Za získání aktuálního data a času není odpovědné přímo PHP, ale operační systém, kde běží. Pokud tedy potřebujete ručně změnit čas, změňte to přímo tam.

Sponzorované odkazy
Pomohl Vám tento článek?

Kde se bere aktuálně zobrazovaný datum a čas?

PHP interně získává systémový čas z operačního systému serveru.

Jak změnit datum a čas?

O správu aktuálního data a času se stará operační systém, proto změnu musíte provést přímo tam (například příkazem v Terminálu, nebo jakýmkoli jiným způsobem). Na sdíleném hostingu často není možné datum změnit, ale můžeme si pomoci přímo v PHP za pomoci vlastní funkce, kde si aktuální datum a čas dopočítáme.

Proměnná $diff obsahuje počet sekund, o které je serverový čas napřed vůči realitě. Pokud je čas zpožděný, tak uvedeme záporné číslo.

echo getDate();
echo date('H:i', getDate());

function getDate() {
    $diff = 60; // 60 s = 1 min
    return date('U') - $diff;
}

Jak správně získat datum a čas od uživatele?

Takhle:

Od nástupu HTML5 existuje několik nových formulářových prvků, které slouží přímo pro získání data a času. Mnoho webových prohlížečů je vykresluje jako hezký klikací kalendář, takže je výběr pohodlný.

Nikdy však nezapomínejte na to, že není dobré uživatele omezovat nějakým konkrétním formátem, jako to mají v oblibě formuláře na úřadě. Uživatel si může zkrátka psát „co chce“ a my si formát převedeme sami. Výborně k tomu slouží funkce strtotime(), které předáme uživatelský vstup jako string a ona vrátí zadaný čas jako timestamp.

Občas potřebujeme datum v nějaké přesné podobě (například pro předání nějaké externí službě, nebo konzistentní výpis), v takovém případě uživatelský vstup nejprve převedeme na timestamp funkcí strtotime() a následně jej přeformátujeme běžným způsobem funkcí date("Formátovací značky", timestamp).

HTML formulář:

<form>
    <input type="datetime">
    <input type="submit">
</form>

Zpracování v PHP:

$form = '20. 07. 2014';

$timestamp = strtotime($form);

echo date('Y', $timestamp); // 2014