PHP Function date_date_set()
Learn how PHP's date_date_set() and DateTime::setDate() change the year, month, and day of a DateTime object, with examples and common gotchas.
In PHP, date_date_set() and its object-oriented twin DateTime::setDate() set a new date (year, month, and day) on an existing DateTime object. The time portion of the object is left untouched — only the calendar date changes. This is the date-side counterpart to DateTime::setTime(), which changes only the clock time.
Use it when you already have a DateTime object and want to move it to a specific day without rebuilding the object from a string.
Syntax
setDate() is available both as a method and as a procedural function. The two forms do exactly the same thing:
The syntax for DateTime::setDate() and date_date_set()
// Object-oriented style
$datetime->setDate($year, $month, $day);
// Procedural style
date_date_set($datetime, $year, $month, $day);Where:
$datetimeis theDateTimeobject to modify.$yearis the new year (e.g.2024).$monthis the new month (1–12).$dayis the new day of the month (1–31).
The method returns the same DateTime object so calls can be chained. The existing time, microseconds, and timezone of the object are all preserved.
Example Usage
Let's set a new date on a DateTime object while keeping its original time:
Example of the PHP DateTime::setDate() method
We create a DateTime for 2000-01-01 12:30:00, then call setDate() to change the date to 15 July 2024. Because setDate() only touches the calendar date, the 12:30:00 time survives. We then use the format() method to print the result:
2024-07-15 12:30:00Procedural Style
If you prefer (or are reading older code), the same change can be written with date_date_set(). It takes the object as its first argument:
<?php
$date = date_create('2000-01-01');
date_date_set($date, 2024, 7, 15);
echo $date->format('Y-m-d');This prints 2024-07-15. Here date_create() builds the object — it is the procedural equivalent of new DateTime.
Out-of-Range Days Roll Over
Like the rest of the DateTime API, setDate() does not validate the day against the length of the month. Instead it normalizes the value and carries any overflow into the next month. Asking for "February 31st" gives you a date in March:
<?php
$date = new DateTime('2024-01-31');
$date->setDate(2024, 2, 31);
echo $date->format('Y-m-d');This prints 2024-03-02: February 2024 has 29 days, so the 31st is 2 days past the end of the month and lands on March 2nd. This rollover is convenient for date arithmetic but a common source of silent bugs if you expected an exception. To shift a date by a relative amount instead, use modify(), add(), or sub().
Mutable vs. Immutable
DateTime is mutable: setDate() changes the object in place and returns that same object. If the value is shared elsewhere in your code, every reference sees the change. To avoid accidental mutation, use DateTimeImmutable, whose setDate() returns a new instance and leaves the original alone:
<?php
$original = new DateTimeImmutable('2000-01-01');
$changed = $original->setDate(2024, 7, 15);
echo $original->format('Y-m-d'), ' | ', $changed->format('Y-m-d');This prints 2000-01-01 | 2024-07-15: $original is untouched, and $changed holds the new date. With the mutable DateTime, both variables would point at the same modified object.
Related Methods
setDate() rarely travels alone. You'll often combine it with:
setTime()— change the hour/minute/second of the same object.setTimezone()— convert the object to another timezone.date_default_timezone_set()— set the script-wide default timezone.new DateTime/date_create()— create the object in the first place.
Conclusion
DateTime::setDate() (and the equivalent date_date_set()) is the clean, object-oriented way to change the year, month, and day of a DateTime object while preserving its time and timezone. Remember two things: out-of-range days roll over into the next month rather than throwing, and the mutable DateTime is changed in place — reach for DateTimeImmutable when you need the original to stay intact.