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.

verze: 4.x 3.x 2.x