Dates7 min readExamples run on PHP 8.5.10

date_time_set()

Learn how date_time_set(), the procedural alias of DateTime::setTime(), changes the hour, minute, second and microsecond of a DateTime object.

Signature

date_time_set(
    DateTime $object,
    int $hour,
    int $minute,
    int $second = 0,
    int $microsecond = 0
): DateTime
Available since PHP 5.2.07.48.08.18.28.38.48.5All versions →

Purpose

date_time_set() replaces the time-of-day part of a DateTime object while leaving the calendar date and the time zone alone. It is the procedural alias of DateTime::setTime(), so both forms behave the same way. Use it when you already have a date, such as a booking day or a report date, and need to pin it to a specific time like opening hour or end of business.

Signature

Parameters and defaults

  • $object: the DateTime object to modify. It is changed in place.
  • $hour: the new hour, normally 0 to 23.
  • $minute: the new minute, normally 0 to 59.
  • $second: the new second. It defaults to 0.
  • $microsecond: the new microsecond part. It defaults to 0.

The important detail is that the optional values are not "keep the old value". If you leave out $second, the seconds become 0. The same applies to microseconds. Every call sets the whole time of day.

Return value and failure cases

The function returns the same DateTime object it modified, so you can keep working with either the variable or the return value. Passing something that is not a DateTime, or a value that cannot be used as an integer, raises a TypeError. In particular, a DateTimeImmutable is not accepted by this procedural function. For immutable objects call the method setTime() instead, which returns a new object and leaves the original unchanged.

Out-of-range numbers do not raise an error. They are normalized by carrying into the next unit, which the second example shows.

Example 1: set a time of day

The original time is 08:45:30. After the call the time is 14:30:00, because the omitted seconds reset to zero.

Example
<?php
$date = new DateTime('2024-03-15 08:45:30', new DateTimeZone('UTC'));
date_time_set($date, 14, 30);
echo $date->format('Y-m-d H:i:s'), "\n";
Output
2024-03-15 14:30:00

Example 2: values that overflow

Hour 25, minute 61 and second 61 are not rejected. They roll forward from midnight of the same day. 25 hours reaches 01:00 the next day, 61 minutes adds another hour and one minute, and 61 seconds adds a minute and one second. Because 2024 is a leap year, the date lands on February 29.

Example
<?php
$date = new DateTime('2024-02-28 10:00:00', new DateTimeZone('UTC'));
date_time_set($date, 25, 61, 61);
echo $date->format('Y-m-d H:i:s'), "\n";
Output
2024-02-29 02:02:01

Example 3: microseconds and the returned object

The fourth and fifth arguments let you set seconds and microseconds. The return value is the very same object, which the strict comparison confirms.

Example
<?php
$date = new DateTime('2024-07-04 00:00:00', new DateTimeZone('UTC'));
$result = date_time_set($date, 9, 5, 7, 123456);
echo json_encode([$result === $date, $date->format('Y-m-d H:i:s.u')], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[true,"2024-07-04 09:05:07.123456"]

Edge cases

  • Mutation: the object you pass in is modified. If another part of your code still needs the original time, call clone first.
  • Reset behavior: a call such as date_time_set($d, 9, 0) also clears seconds and microseconds, even if they were non-zero before.
  • Overflow: numbers outside the normal ranges are carried into larger units, so the date part can change as well as the time.
  • Time zones: the time is interpreted in the time zone stored in the object. In zones with daylight saving changes, a requested local time may not exist or may be ambiguous, so be careful near transitions and prefer UTC for fixed calculations.
  • Date unchanged: the function never sets the year, month or day directly. Use date_date_set() for that part.

Common mistakes

  1. Expecting seconds to be kept. Calling the function with only hour and minute sets seconds to zero.
  2. Passing a DateTimeImmutable. The procedural function expects DateTime. With immutable objects use $immutable->setTime(...) and store the returned object.
  3. Ignoring in-place changes. Reusing the same object after calling the function means you are now working with the new time.
  4. Relying on overflow by accident. Hour 24 or minute 60 silently moves to the next day or hour. Validate user input first if overflow would be a bug.
  5. Mixing up the argument order. The object comes first, then hour, minute, second and microsecond.
  • DateTime::setTime(): the method form of this function.
  • date_date_set(): changes year, month and day.
  • date_timestamp_set(): sets the date and time from a Unix timestamp.
  • date_create(): creates a DateTime object to modify.
  • date_format(): formats the result as text.

Recap

date_time_set() is an alias of DateTime::setTime(). It changes the hour, minute, second and microsecond of a DateTime in place, resets omitted seconds and microseconds to zero, normalizes out-of-range numbers by carrying them into the date, and returns the same object.

Tested examples

Set a time of day
<?php
$date = new DateTime('2024-03-15 08:45:30', new DateTimeZone('UTC'));
date_time_set($date, 14, 30);
echo $date->format('Y-m-d H:i:s'), "\n";
Output
2024-03-15 14:30:00
Values that overflow
<?php
$date = new DateTime('2024-02-28 10:00:00', new DateTimeZone('UTC'));
date_time_set($date, 25, 61, 61);
echo $date->format('Y-m-d H:i:s'), "\n";
Output
2024-02-29 02:02:01
Microseconds and the returned object
<?php
$date = new DateTime('2024-07-04 00:00:00', new DateTimeZone('UTC'));
$result = date_time_set($date, 9, 5, 7, 123456);
echo json_encode([$result === $date, $date->format('Y-m-d H:i:s.u')], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[true,"2024-07-04 09:05:07.123456"]