W3docs

date_timezone_set()

Learn how PHP's date_timezone_set() converts a DateTime object to another timezone without changing the instant. Syntax, DST handling, and examples.

Introduction

date_timezone_set() changes the timezone of an existing DateTime object. Crucially, it does not change the underlying instant in time — it changes the wall-clock representation of that instant. The same moment is simply re-expressed in a different timezone, so the displayed hours and minutes shift while the absolute point on the timeline stays identical.

This makes it the right tool whenever you have a date/time in one zone and need to show it in another: converting a stored UTC timestamp into a user's local time, or comparing events recorded across different regions.

date_timezone_set() is the procedural alias of the DateTime::setTimezone() method — both do exactly the same thing.

Syntax

date_timezone_set(DateTime $object, DateTimeZone $timezone): DateTime|false
  • $object — the DateTime object whose timezone you want to change.
  • $timezone — a DateTimeZone object holding the target zone (for example new DateTimeZone('Asia/Tokyo')).

The function mutates $object in place and returns the same instance on success (handy for chaining), or false on failure. Because it modifies the original object, there is no separate "copy" — the input object itself changes.

Basic example

php— editable, runs on the server
2023-03-03 21:00:00

The object starts at 12:00 in London (Europe/London, which is UTC+0 in March). Tokyo is 9 hours ahead, so the same instant is displayed as 21:00. Nothing about the actual moment changed — only the zone it is shown in.

The instant stays the same — only the display shifts

This is the single most important thing to understand about date_timezone_set(). Compare the value before and after the conversion:

<?php
$date = new DateTime('2023-03-03 12:00:00', new DateTimeZone('Europe/London'));
echo $date->format('Y-m-d H:i:s P'), "\n";   // before

date_timezone_set($date, new DateTimeZone('Asia/Tokyo'));
echo $date->format('Y-m-d H:i:s P'), "\n";   // after
2023-03-03 12:00:00 +00:00
2023-03-03 21:00:00 +09:00

The wall-clock time and the UTC offset both change, but 12:00 +00:00 and 21:00 +09:00 are the same point in time. If you only need the absolute instant (for example, a UNIX timestamp), it will be unchanged.

If you instead want to replace the wall-clock time without converting it, do not use this function — set the time directly with date_time_set().

Daylight saving time is handled for you

Because the conversion goes through a real DateTimeZone, daylight saving (DST) rules are applied automatically. New York is UTC-5 in winter but UTC-4 in summer, and date_timezone_set() picks the correct offset for the date in question:

<?php
$utc = new DateTime('2023-06-21 12:00:00', new DateTimeZone('UTC'));
date_timezone_set($utc, new DateTimeZone('America/New_York'));
echo $utc->format('Y-m-d H:i:s');
2023-06-21 08:00:00

In June, New York is on Eastern Daylight Time (UTC-4), so 12:00 UTC becomes 08:00. Run the same code with a January date and you would get 07:00 (UTC-5) instead — without any change to your code. This is why you should always use IANA zone identifiers like America/New_York rather than fixed offsets like -05:00.

Procedural vs. object-oriented style

date_timezone_set($obj, $tz) and $obj->setTimezone($tz) are interchangeable. The method form usually reads better and chains naturally:

<?php
$london = (new DateTime('2023-03-03 12:00:00', new DateTimeZone('Europe/London')))
    ->setTimezone(new DateTimeZone('Asia/Tokyo'));
echo $london->format('Y-m-d H:i:s');
2023-03-03 21:00:00

Common use cases

  • Display stored UTC times in a user's zone. Store every timestamp in UTC, then convert on output with date_timezone_set() for each user's preferred timezone.
  • Normalize times from multiple regions before comparing or sorting them.
  • Build region-aware reports, showing the same event in several zones side by side.

Things to watch out for

  • It mutates the original object. If you need to keep the source value, clone it first: $copy = clone $date; then convert $copy.
  • It does not parse or set a new date — it only re-projects the existing instant. Use date_create() to build a DateTime and date_time_set() to overwrite the time.
  • To read back the zone currently attached to an object, use date_timezone_get().
  • Don't confuse it with date_default_timezone_set(), which sets the script-wide default zone for all date/time functions — a completely different job.

Diagram

graph LR
A[DateTime Object] --> B((date_timezone_set))
C[Target DateTimeZone] --> B
B --> D[Same instant, new wall-clock display]

Practice

Practice
What does the date_timezone_set() function in PHP do?
What does the date_timezone_set() function in PHP do?
Was this page helpful?