← All writing

Avoid changing the original date while calculating a reminder

PHP 8.3+Sources checked 2026-09-13

An invoice has a due date, and a reminder should go out three days earlier. With a mutable date object, calculating the reminder can also change the original object. The invoice then appears to have a different due date later in the request.

Return a new date value

<?php
$due = new DateTimeImmutable('2026-10-10 09:00:00', new DateTimeZone('UTC'));
$reminder = $due->modify('-3 days');
assert($due->format('Y-m-d') === '2026-10-10');
assert($reminder->format('Y-m-d') === '2026-10-07');

DateTimeImmutable returns a new instance for modification. Assign that result to a name that explains its purpose. Calling modify and ignoring the return value does not change the original, which is another common source of confusion when migrating from mutable dates.

Calendar rules still matter

Three calendar days and 72 elapsed hours can differ across daylight-saving transitions. Pick a timezone and a rule that matches the reminder contract. A due date with no time-of-day may deserve a date-only representation rather than midnight in a timezone chosen by accident.

At application boundaries, be clear about conversion between database timestamps, UTC, and the customer's timezone. Immutability prevents accidental object mutation; it does not solve an incorrect timezone assumption.

Test that the original value remains unchanged, that the new date is correct, and that a month boundary behaves as expected. For timezone-sensitive reminders, include a daylight-saving transition in a relevant customer timezone. Keep those tests separate from tests that only check the formatting of a date label.

Reference

Official documentation. The examples here illustrate the stated boundary; adapt them to your application and test its failure paths.