Signature
date_modify(DateTime $object, string $modifier): DateTime|falsePurpose
date_modify() is the procedural alias of DateTime::modify(). It takes a DateTime object and changes it in place using a textual modifier such as +1 day, last day of this month or next monday. Use it when your code is written in the procedural style (date_create(), date_format(), date_diff()) and you need to shift a date relative to its current value.
Signature
Parameters
$objectis theDateTimeto change. There is no default. The object is modified directly, so the caller's variable sees the new value.$modifieris a string in PHP's relative date format syntax. There is no default. It can contain offsets like+2 weeksor-3 hours, keywords liketomorrowormidnight, weekday names, and phrases such asfirst day of next month.
The function accepts only DateTime. A DateTimeImmutable is rejected with a TypeError, because an immutable object cannot be changed in place. For immutable values, call the modify() method instead; it returns a new object.
Return value and failure cases
On success the function returns the same DateTime object you passed in, now holding the new date and time. That is why comparing the return value with the argument using === is true.
The declared return type includes false, which signals that the modifier could not be parsed. Treat modifier strings from user input as untrusted and validate them, or check the result. Because this function is an alias of DateTime::modify(), consult that method's page for exactly how failures are reported in the style of API you use. The examples below use only valid, fixed modifiers.
Example 1: Add a relative offset
The time of day is preserved when you add a day offset.
date_default_timezone_set('UTC');
$d = date_create('2024-01-31 10:00:00');
date_modify($d, '+1 day');
echo date_format($d, 'Y-m-d H:i:s'), "\n";2024-02-01 10:00:00
Example 2: The same object is changed and returned
The return value is not a copy. It is the object you passed in. Phrases such as last day of this month change the date but keep the time.
date_default_timezone_set('UTC');
$a = new DateTime('2024-03-10 08:30:00');
$b = date_modify($a, 'last day of this month');
var_dump($a === $b);
echo $a->format('Y-m-d H:i'), "\n";bool(true) 2024-03-31 08:30
Example 3: Month overflow versus a safe month-end
Adding a month to January 31 produces a day that does not exist in February, so the extra days roll into March. The last day of next month phrase avoids that overflow.
$base = new DateTime('2024-01-31 00:00:00', new DateTimeZone('UTC'));
$overflow = clone $base;
date_modify($overflow, '+1 month');
$safe = clone $base;
date_modify($safe, 'last day of next month');
echo json_encode([
'overflow' => $overflow->format('Y-m-d'),
'safe' => $safe->format('Y-m-d'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"overflow":"2024-03-02","safe":"2024-02-29"}
Edge cases
- Month arithmetic is not clamped.
+1 monthadds one to the month number and then normalizes the day, so January 31 becomes March 2 in 2024. Uselast day oforfirst day ofwhen you mean calendar boundaries. - Weekday names reset the time. A modifier like
next mondayormonday this weekmoves to that weekday at midnight unless you also give a time, for examplenext monday 09:00. - Time zone matters. The modification happens in the object's own time zone. Around daylight-saving changes, adding
+1 dayand adding+24 hourscan give different wall-clock results. Fixed UTC examples avoid this ambiguity. - Several parts in one string are applied together, such as
+1 week 2 days. Keep modifiers simple and readable, and split complex logic into several calls.
Common mistakes
- Expecting a new object. Code like
$next = date_modify($date, '+1 day');leaves$dateand$nextpointing to the same changed object. Clone first if you need the original. - Passing
DateTimeImmutable. The function is typed forDateTime. Use$immutable->modify('+1 day')and keep the returned object. - Ignoring month overflow. Billing and deadline code that adds months from day 29, 30 or 31 often produces unexpected dates.
- Forgetting the time part. Modifiers like
midnight,noon,tomorrowand weekday names interact with the time of day. Check the formatted result with the time included. - Not handling invalid strings. A typo in a modifier is a failure case, not a harmless no-op.
Related functions
DateTime::modify()is the object-oriented form that this function aliases.DateTimeImmutable::modify()returns a modified copy.date_add()anddate_sub()change a date by aDateInterval.date_create()builds theDateTimeobject to modify.date_format()turns the result into a string.date_timestamp_set()anddate_date_set()set absolute values instead of relative ones.
Recap
date_modify() takes a DateTime and a relative modifier string, changes the object in place and returns that same object, or false when the modifier is invalid. Remember that it mutates, accepts only DateTime, can overflow at month ends, and may reset the time with weekday keywords. Prefer explicit phrases such as last day of next month when you mean calendar boundaries.
Tested examples
date_default_timezone_set('UTC');
$d = date_create('2024-01-31 10:00:00');
date_modify($d, '+1 day');
echo date_format($d, 'Y-m-d H:i:s'), "\n";
2024-02-01 10:00:00
date_default_timezone_set('UTC');
$a = new DateTime('2024-03-10 08:30:00');
$b = date_modify($a, 'last day of this month');
var_dump($a === $b);
echo $a->format('Y-m-d H:i'), "\n";
bool(true) 2024-03-31 08:30
$base = new DateTime('2024-01-31 00:00:00', new DateTimeZone('UTC'));
$overflow = clone $base;
date_modify($overflow, '+1 month');
$safe = clone $base;
date_modify($safe, 'last day of next month');
echo json_encode([
'overflow' => $overflow->format('Y-m-d'),
'safe' => $safe->format('Y-m-d'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
{"overflow":"2024-03-02","safe":"2024-02-29"}