Data i czas

Nette oferuje dwie klasy do pracy z datą i czasem: Nette\Utils\DateTimeImmutable (niezmienną, zalecaną) i Nette\Utils\DateTime (zmienną). Obie rozszerzają natywne klasy PHP, więc każda natywna metoda pozostaje dostępna, i dodają te same dwa usprawnienia.

Po pierwsze, są rygorystyczne. Podczas gdy PHP po cichu akceptuje nieprawidłowe daty, takie jak 0000-00-00 (zamienia na -0001-11-30) czy 2024-02-31 (zamienia na 2024-03-02), te klasy zamiast tego zgłaszają wyjątek.

Po drugie, naprawiają zachowanie przy zmianach czasu letniego (DST), gdzie w natywnym PHP dodanie czasu względnego (np. +100 minutes) może dać wcześniejszy czas niż dodanie krótszego okresu (np. +50 minutes). Te klasy zapewniają, że arytmetyka działa intuicyjnie i +100 minutes jest zawsze więcej niż +50 minutes.

Instalacja:

composer require nette/utils

Niezmienna czy zmienna?

Klasa DateTimeImmutable jest dostępna od wersji 4.1.5 i jest zalecanym wyborem. Każda metoda modyfikująca zwraca nową instancję, zamiast zmieniać oryginał, więc obiekt, który gdzieś przechowujesz albo przekazałeś do funkcji, nigdy nie zmieni się nieoczekiwanie:

use Nette\Utils\DateTimeImmutable;

$date = new DateTimeImmutable('2024-02-26');
$next = $date->modify('+1 day');
echo $date; // 2024-02-26 00:00:00  (bez zmian)
echo $next; // 2024-02-27 00:00:00  (nowy obiekt)

DateTime jest zmienna: to samo wywołanie zmienia obiekt w miejscu. Nie jest przestarzała, ale w nowym kodzie preferowany jest wariant niezmienny.

use Nette\Utils\DateTime;

$date = new DateTime('2024-02-26');
$date->modify('+1 day');
echo $date; // 2024-02-27 00:00:00  (oryginał się zmienił)

Ponieważ obie klasy rozszerzają natywne, nadal używasz metod, które już znasz: format(), getTimestamp(), add(), sub(), diff(), setTimezone(), operatorów porównania itd. Na DateTimeImmutable wszystkie metody modyfikujące zwracają nową instancję. Reszta tej strony opisuje tylko to, co Nette dodaje ponad to; o ile nie zaznaczono inaczej, wszystko działa tak samo w obu klasach.

Tworzenie obiektów

static from (string|int|\DateTimeInterface|null $time)static

Tworzy obiekt ze stringa, uniksowego timestampu albo innego obiektu DateTimeInterface. null oznacza bieżący czas. Zgłasza wyjątek, jeśli data i czas nie są prawidłowe.

DateTimeImmutable::from(1_138_013_640); // z uniksowego timestampu, w domyślnej strefie czasowej
DateTimeImmutable::from('1994-02-26 04:15:32'); // ze stringa
DateTimeImmutable::from('1994-02-26'); // z daty, czas będzie 00:00:00
DateTimeImmutable::from(null); // bieżąca data i czas

static fromParts (int $year, int $month, int $day, int $hour=0, int $minute=0, float $second=0.0)static

Tworzy obiekt z poszczególnych części albo zgłasza wyjątek, jeśli data i czas nie są prawidłowe.

DateTimeImmutable::fromParts(1994, 2, 26, 4, 15, 32);

static createFromFormat (string $format, string $datetime, string|\DateTimeZone|null $timezone=null): static|false

Rozszerza natywną DateTime::createFromFormat o możliwość podania strefy czasowej jako stringa.

DateTimeImmutable::createFromFormat('d.m.Y', '26.02.1994', 'Europe/London');

Rygorystyczna walidacja

Nieprawidłowa data albo czas nigdy nie są po cichu korygowane; zawsze zgłaszany jest wyjątek. Dotyczy to każdego sposobu utworzenia albo zmiany obiektu: konstruktora, from(), fromParts() oraz metod setDate() i setTime().

new DateTimeImmutable('2024-02-31');         // zgłasza (luty nie ma 31.)
DateTimeImmutable::fromParts(2024, 2, 31);   // zgłasza
$date->setDate(2024, 2, 31);                 // zgłasza
$date->setTime(25, 0);                       // zgłasza (nie ma 25. godziny)

Wynik tekstowy i JSON

__toString() zwraca datę i czas w formacie Y-m-d H:i:s, więc obiekt można wypisać albo od razu konkatenować:

echo $date; // '2017-02-03 04:15:32'

Obie klasy implementują JsonSerializable i serializują się do formatu ISO 8601, powszechnie używanego w JavaScripcie:

echo json_encode($date); // '"2017-02-03T04:15:32+01:00"'

Dodatkowe możliwości DateTime

Zmienna klasa DateTime ma kilka dodatkowych elementów, które mają sens tylko dla obiektu zmiennego i dlatego nie wchodzą w skład DateTimeImmutable.

Jej metoda from() traktuje też małą liczbę jako przesunięcie w sekundach względem bieżącego czasu. Wariant niezmienny celowo pomija ten skrót – tam liczba jest zawsze dosłownym timestampem.

DateTime::from(42); // bieżący czas plus 42 sekundy

modifyClone(string $modify=''): static zwraca zmodyfikowaną kopię i pozostawia oryginał nietknięty. Na obiekcie zmiennym daje to, co na niezmiennym zapewnia za darmo modify():

$original = DateTime::from('2017-02-03');
$clone = $original->modifyClone('+1 day');
$original->format('Y-m-d'); // '2017-02-03'  (bez zmian)
$clone->format('Y-m-d');    // '2017-02-04'

DateTime::relativeToSeconds(string $relativeTime): int konwertuje string z czasem względnym na sekundy:

DateTime::relativeToSeconds('1 minute'); // 60
DateTime::relativeToSeconds('-1 hour'); // -3600

Wreszcie DateTime definiuje stałe MINUTE, HOUR, DAY, WEEK, MONTH i YEAR wyrażające długość w sekundach; MONTH i YEAR są wartościami średnimi, więc używaj ich tylko do zgrubnych oszacowań.

wersja: 4.x