Wyobraź sobie, że tworzysz system rezerwacji. Masz klasę Reservation, która przechowuje termin wizyty. W pewnym momencie musisz przesunąć datę o jeden dzień, więc robisz:
$reservation->date->modify('+1 day');I nagle… wszystkie rezerwacje mają nową datę! 😨
Brzmi absurdalnie? Niestety, to realny scenariusz, kiedy używasz DateTime zamiast DateTimeImmutable. W tym wpisie pokażę Ci, dlaczego warto wybrać niemutowalność i jak uniknąć trudnych do wykrycia błędów.
DateTime – obiekt, który zmienia się w miejscu
DateTime to mutowalna (zmienialna) klasa PHP. Oznacza to, że gdy wykonasz na niej operację modyfikującą (np. modify()), zmieniasz oryginalny obiekt, a nie tworzysz nowy. Rzućmy okiem na prostą operację na dacie:
$date = new DateTime('2025-07-20');
$date->modify('+1 day');
echo $date->format('Y-m-d'); // 2025-07-21Proste? Tak.
Niebezpieczne? Jeszcze bardziej.
Jeśli ten obiekt był gdzieś przekazany przez referencję, zmienisz stan wszędzie. W dużych systemach to tykająca bomba.
DateTimeImmutable – obiekt, który nie zmienia się nigdy
DateTimeImmutable działa tak samo jak DateTime, z tą różnicą, że każda operacja zwraca nowy obiekt.
$date = new DateTimeImmutable('2025-07-20');
$newDate = $date->modify('+1 day');
echo $date->format('Y-m-d'); // 2025-07-20
echo $newDate->format('Y-m-d'); // 2025-07-21To znaczy: oryginał zostaje nietknięty. Masz 100% kontroli nad tym, co i kiedy się zmienia.
Dlaczego to takie ważne?
W PHP, a szczególnie w frameworkach takich jak Symfony czy Laravel, bardzo łatwo nieświadomie przekazać referencję do daty. Przykłady realnych problemów:
Efekty uboczne w encjach
Masz encję User z createdAt, a gdzieś robisz:
$user->getCreatedAt()->modify('+7 days');Efekt? Zmieniasz datę utworzenia użytkownika 😬
Reużywanie tego samego obiektu
Tworzysz $now = new DateTime();, a potem używasz go w wielu miejscach. Każda modyfikacja zmienia pierwotną wartość.
Testy
Testujesz logikę zależną od daty? DateTimeImmutable gwarantuje, że nie „psujesz” przypadkiem danych wejściowych między testami.
Kiedy używać DateTimeImmutable?
Zawsze, jeśli nie masz konkretnego powodu, żeby tego nie robić.
Symfony od wersji 6.2 już domyślnie traktuje DateTimeImmutable jako typ preferowany np. w serializerach, formularzach i walidacjach. Laravel też nie robi problemów, o ile jawnie pracujesz z typami. Przy okazji zapraszam do mojego wpisu gdzie porównuje frameworki Symfony i Laravel.
Nie bez powodu większość języków nowoczesnych (np. JavaScript z Date-fns, Python z datetime, Go z time.Time) idzie w stronę niemutowalnych dat. To po prostu bezpieczniejsze, bardziej przewidywalne i testowalne.
Masz pytania, przykład ze swojego projektu, który zniszczył Ci tydzień przez DateTime?
Napisz do mnie lub zostaw komentarz, możemy wspólnie to ogarnąć.

Nikt jeszcze nie komentował. Bądź pierwszy!