W3docs

date_timezone_set()

Узнайте, как date_timezone_set() в PHP переводит объект DateTime в другой часовой пояс без изменения момента времени. Синтаксис, DST и примеры.

Введение

date_timezone_set() изменяет часовой пояс существующего object DateTime. Важно понимать: функция не меняет абсолютный момент времени — она меняет представление на часах для того же момента. Один и тот же момент просто выражается в другом часовом поясе: отображаемые часы и минуты сдвигаются, а сама точка на временной шкале остаётся неизменной.

Это правильный инструмент, когда у вас есть дата/время в одном поясе и нужно отобразить их в другом: например, для перевода сохранённой UTC-метки в локальное время пользователя или сравнения событий, записанных в разных регионах.

date_timezone_set() — процедурный псевдоним метода DateTime::setTimezone(): оба делают ровно одно и то же.

Синтаксис

date_timezone_set(DateTime $object, DateTimeZone $timezone): DateTime|false
  • $object — object DateTime, часовой пояс которого нужно изменить.
  • $timezone — object DateTimeZone, задающий целевой пояс (например, new DateTimeZone('Asia/Tokyo')).

Функция изменяет $object на месте и возвращает тот же экземпляр при успехе (удобно для цепочек вызовов) либо false при ошибке. Поскольку она модифицирует исходный object, отдельной «копии» не создаётся — изменяется именно переданный object.

Базовый пример

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

Object создаётся с временем 12:00 по Лондону (Europe/London, то есть UTC+0 в марте). Токио опережает Лондон на 9 часов, поэтому тот же момент отображается как 21:00. Сам момент не изменился — изменился лишь часовой пояс отображения.

Момент остаётся прежним — меняется только отображение

Это самое важное, что нужно понять о date_timezone_set(). Сравните значение до и после преобразования:

<?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

Показания часов и UTC-смещение изменились, однако 12:00 +00:00 и 21:00 +09:00 — это один и тот же момент времени. Если вам нужен только абсолютный момент (например, UNIX-timestamp), он останется неизменным.

Если вы хотите заменить показания часов без конвертации, не используйте эту функцию — задайте время напрямую с помощью date_time_set().

Переход на летнее время обрабатывается автоматически

Поскольку преобразование выполняется через настоящий DateTimeZone, правила перехода на летнее время (DST) применяются автоматически. Нью-Йорк находится в UTC-5 зимой и в UTC-4 летом, и date_timezone_set() автоматически выбирает правильное смещение для указанной даты:

<?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

В июне Нью-Йорк работает по восточному летнему времени (UTC-4), поэтому 12:00 UTC превращается в 08:00. Запустите тот же код с датой в январе — и получите 07:00 (UTC-5) без каких-либо изменений в коде. Вот почему всегда следует использовать идентификаторы часовых поясов IANA, такие как America/New_York, а не фиксированные смещения вроде -05:00.

Процедурный и объектно-ориентированный стиль

date_timezone_set($obj, $tz) и $obj->setTimezone($tz) взаимозаменяемы. Форма метода обычно читается лучше и удобна для цепочек вызовов:

<?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

Типичные сценарии использования

  • Отображение UTC-времени в часовом поясе пользователя. Храните все метки времени в UTC, а при выводе конвертируйте их с помощью date_timezone_set() в предпочтительный пояс каждого пользователя.
  • Нормализация времени из разных регионов перед сравнением или сортировкой.
  • Формирование региональных отчётов, в которых одно и то же событие отображается одновременно в нескольких часовых поясах.

На что обратить внимание

  • Функция изменяет исходный object. Если нужно сохранить исходное значение, сначала клонируйте его: $copy = clone $date;, а затем конвертируйте $copy.
  • Функция не разбирает и не устанавливает новую дату — она лишь перепроецирует существующий момент. Используйте date_create() для создания DateTime и date_time_set() для замены времени.
  • Чтобы узнать часовой пояс, который в данный момент связан с object, используйте date_timezone_get().
  • Не путайте эту функцию с date_default_timezone_set(), которая устанавливает часовой пояс по умолчанию для всех функций даты и времени в скрипте — это совершенно другая задача.

Диаграмма

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

Практика

Практика
Что делает функция date_timezone_set() в PHP?
Что делает функция date_timezone_set() в PHP?
Was this page helpful?