Datum a čas
Nette nabízí dvě třídy pro práci s datem a časem: Nette\Utils\DateTimeImmutable (immutable, doporučená) a Nette\Utils\DateTime (mutable). Obě rozšiřují nativní PHP třídy, takže všechny nativní metody zůstávají k dispozici, a přidávají stejná dvě vylepšení.
Zaprvé jsou striktní. Zatímco PHP tiše akceptuje nesmyslná data jako 0000-00-00 (převede na
-0001-11-30) nebo 2024-02-31 (převede na 2024-03-02), tyto třídy místo toho vyhodí
výjimku.
Zadruhé opravují chování při přechodu na letní/zimní čas, kdy v nativním PHP může přičtení relativního
času (např. +100 minutes) vést k dřívějšímu výslednému
času než přičtení kratšího úseku (např. +50 minutes). Tyto třídy zajišťují, že aritmetika funguje
intuitivně a +100 minutes je vždy více než +50 minutes.
Instalace:
composer require nette/utils
Immutable, nebo mutable?
Třída DateTimeImmutable je k dispozici od verze 4.1.5 a je doporučenou volbou. Každá upravující metoda
vrací novou instanci místo změny původní, takže objekt, který máte uložený nebo předaný do funkce, se nikdy
nezmění nečekaně:
use Nette\Utils\DateTimeImmutable;
$date = new DateTimeImmutable('2024-02-26');
$next = $date->modify('+1 day');
echo $date; // 2024-02-26 00:00:00 (beze změny)
echo $next; // 2024-02-27 00:00:00 (nový objekt)
DateTime je mutable: totéž volání změní objekt na místě. Není zavržená (deprecated), ale pro nový kód
je vhodnější immutable varianta.
use Nette\Utils\DateTime;
$date = new DateTime('2024-02-26');
$date->modify('+1 day');
echo $date; // 2024-02-27 00:00:00 (původní objekt se změnil)
Protože obě třídy rozšiřují nativní, dál používáte metody, které už znáte: format(),
getTimestamp(), add(), sub(), diff(), setTimezone(), operátory
porovnání a další. U DateTimeImmutable všechny ty upravující vracejí novou instanci. Zbytek této stránky
popisuje jen to, co Nette přidává navíc; není-li uvedeno jinak, vše funguje na obou třídách stejně.
Vytváření objektů
static from (string|int|\DateTimeInterface|null $time): static
Vytvoří objekt z řetězce, UNIX timestampu nebo jiného objektu DateTimeInterface. null znamená aktuální čas. Vyhodí výjimku,
pokud datum a čas není platný.
DateTimeImmutable::from(1_138_013_640); // z UNIX timestampu, s výchozí časovou zónou
DateTimeImmutable::from('1994-02-26 04:15:32'); // z řetězce
DateTimeImmutable::from('1994-02-26'); // z data, čas bude 00:00:00
DateTimeImmutable::from(null); // aktuální datum a čas
static fromParts (int $year, int $month, int $day, int $hour=0, int $minute=0, float $second=0.0): static
Vytvoří objekt z jednotlivých částí, nebo vyhodí výjimku, pokud datum a čas není platný.
DateTimeImmutable::fromParts(1994, 2, 26, 4, 15, 32);
static createFromFormat (string $format, string $datetime, string|\DateTimeZone|null $timezone=null): static|false
Rozšiřuje nativní DateTime::createFromFormat o možnost zadat časovou zónu jako řetězec.
DateTimeImmutable::createFromFormat('d.m.Y', '26.02.1994', 'Europe/London');
Striktní validace
Neplatné datum ani čas se nikdy tiše neupraví; vždy vyhodí výjimku. Platí to pro všechny způsoby, jak objekt
vytvořit nebo změnit: konstruktor, from(), fromParts() i metody setDate() a
setTime().
new DateTimeImmutable('2024-02-31'); // vyhodí výjimku (únor nemá 31. den)
DateTimeImmutable::fromParts(2024, 2, 31); // vyhodí výjimku
$date->setDate(2024, 2, 31); // vyhodí výjimku
$date->setTime(25, 0); // vyhodí výjimku (25. hodina neexistuje)
Výstup do řetězce a JSON
__toString() vrací datum a čas ve formátu Y-m-d H:i:s, takže objekt lze přímo vypsat nebo
zřetězit:
echo $date; // '2017-02-03 04:15:32'
Obě třídy implementují JsonSerializable a serializují se do formátu ISO 8601, který se běžně používá
v JavaScriptu:
echo json_encode($date); // '"2017-02-03T04:15:32+01:00"'
Metody navíc ve třídě DateTime
Mutable DateTime nese několik prvků navíc, které dávají smysl jen u mutable objektu, a proto nejsou
součástí DateTimeImmutable.
Její metoda from() navíc bere malé číslo jako posun v sekundách od aktuálního času. Immutable varianta
tuto zkratku záměrně vynechává; tam je číslo vždy doslovný timestamp.
DateTime::from(42); // aktuální čas plus 42 sekund
modifyClone(string $modify=''): static vrátí upravenou kopii a původní objekt nechá beze změny. U mutable
objektu poskytuje to, co modify() u immutable dává zadarmo:
$original = DateTime::from('2017-02-03');
$clone = $original->modifyClone('+1 day');
$original->format('Y-m-d'); // '2017-02-03' (beze změny)
$clone->format('Y-m-d'); // '2017-02-04'
DateTime::relativeToSeconds(string $relativeTime): int převede relativní časový údaj na
sekundy:
DateTime::relativeToSeconds('1 minute'); // 60
DateTime::relativeToSeconds('-1 hour'); // -3600
Nakonec DateTime definuje konstanty MINUTE, HOUR, DAY, WEEK,
MONTH a YEAR vyjadřující délku v sekundách; MONTH a YEAR jsou průměry,
používejte je proto jen pro hrubé odhady.