PHP provides two main classes for working with dates and times: DateTime and DateTimeImmutable.
Both classes let you create dates, format them, change timezones, and perform date calculations. However, they behave differently when you modify a date.
In this guide, you'll learn the difference between mutable and immutable dates, see practical examples, and understand which class to choose for your PHP applications.
What Is the Difference?
The main difference is how the classes handle modifications.
- DateTime is mutable: Changing the date modifies the existing object.
- DateTimeImmutable is immutable: Changing the date creates a new object, leaving the original unchanged.
Both classes provide familiar methods such as format(), modify(), add(), and setTimezone().
Let's see how their behavior differs.
Working with DateTime
The DateTime class allows you to modify an existing date object.
<?php
$date = new DateTime("2026-10-20");
echo $date->format("Y-m-d") . PHP_EOL;
$date->modify("+5 days");
echo $date->format("Y-m-d");
Output:
2026-10-20
2026-10-25
The modify() method changes the original $date object.
You don't need to assign the result to another variable because the existing object has already been updated.
This can be convenient when you intentionally want to change a date repeatedly.
Working with DateTimeImmutable
The DateTimeImmutable class works differently. Instead of modifying the current object, its modification methods return a new object.
<?php
$date = new DateTimeImmutable("2026-10-20");
$newDate = $date->modify("+5 days");
echo $date->format("Y-m-d") . PHP_EOL;
echo $newDate->format("Y-m-d");
Output:
2026-10-20
2026-10-25
Notice that $date still contains October 20, while $newDate contains October 25.
This behavior makes it easier to perform date calculations without accidentally changing the original value.
Common mistake: Calling $date->modify("+5 days") without using its return value won't update a DateTimeImmutable object.
DateTime vs DateTimeImmutable Comparison
| Feature | DateTime | DateTimeImmutable |
|---|---|---|
| Can format dates | Yes | Yes |
| Can perform date calculations | Yes | Yes |
| Changes existing object | Yes | No |
| Returns a new object when modified | No | Yes |
| Risk of accidental shared changes | Higher | Lower |
| Recommended for new application code | When mutation is intentional | Generally preferred |
Why Does Immutability Matter?
In PHP, multiple variables can refer to the same object.
With DateTime, changing the object through one variable affects what the other variable sees.
<?php
$deadline = new DateTime("2026-10-20");
$reminder = $deadline;
$reminder->modify("-2 days");
echo $deadline->format("Y-m-d");
Output:
2026-10-18
Even though we modified $reminder, the deadline changed too because both variables refer to the same object.
With DateTimeImmutable, this problem is avoided:
<?php
$deadline = new DateTimeImmutable("2026-10-20");
$reminder = $deadline->modify("-2 days");
echo $deadline->format("Y-m-d") . PHP_EOL;
echo $reminder->format("Y-m-d");
Output:
2026-10-20
2026-10-18
The original deadline remains unchanged, while the reminder receives its own date object.
Practical Example: Calculating Event Reminders
Imagine you're building an event management application.
You need to calculate a reminder date three days before an event without changing the event's scheduled date.
Create a file named event-reminder.php:
<?php
declare(strict_types=1);
function calculateReminder(
DateTimeImmutable $eventDate,
int $daysBefore
): DateTimeImmutable {
if ($daysBefore < 0) {
throw new InvalidArgumentException(
"Days must not be negative."
);
}
return $eventDate->sub(
new DateInterval("P{$daysBefore}D")
);
}
// Set the event date and timezone.
$eventDate = new DateTimeImmutable(
"2026-11-15 14:00:00",
new DateTimeZone("UTC")
);
// Calculate the reminder date.
$reminderDate = calculateReminder($eventDate, 3);
// Display both dates.
echo "Event: "
. $eventDate->format("Y-m-d H:i")
. PHP_EOL;
echo "Reminder: "
. $reminderDate->format("Y-m-d H:i");
Output:
Event: 2026-11-15 14:00
Reminder: 2026-11-12 14:00
The sub() method subtracts the specified interval and returns a new DateTimeImmutable object.
The original event date remains unchanged. We also specify UTC explicitly so the example doesn't depend on the server's default timezone.
Converting Between the Two Classes
PHP provides methods for converting between mutable and immutable date objects.
<?php
$mutable = new DateTime("2026-10-20");
// Convert to an immutable object.
$immutable = DateTimeImmutable::createFromMutable(
$mutable
);
// Convert back to a mutable object.
$mutableAgain = DateTime::createFromImmutable(
$immutable
);
These methods create separate objects, allowing you to use the date representation required by your application.
Both classes also implement DateTimeInterface, which is useful when writing functions that only need to read or format dates and should accept either type.
Which One Should You Use?
For most new PHP applications, DateTimeImmutable is a sensible default.
It helps prevent unintended changes and makes date calculations more predictable, especially when passing objects between functions.
Use DateTime when you specifically need a mutable date object or are working with existing code that expects it.
If you use DateTime but need an independent copy, you can create one using clone.
Key Takeaways
DateTimemodifies the existing date object.DateTimeImmutablereturns a new object when a date changes.- Both classes support formatting, timezones, and date calculations.
- Mutable objects can produce unexpected changes when shared between variables.
- Use
DateTimeImmutablewhen you want predictable date calculations without modifying original values. - Use
DateTimeInterfacewhen a function should accept either class for read-only operations.
Understanding the difference between DateTime and DateTimeImmutable helps you write more reliable PHP applications. Choosing the right class makes date calculations easier to follow and reduces the risk of accidentally changing important dates.