Определение временной зоны для PHP-приложений

Раздел: Администрирование PHP -> Настройка PHP

Глобальная настройка часового пояса в php.ini

Какой способ гарантирует единый часовой пояс для всех PHP-скриптов на сервере без вмешательства в код?

Наиболее эффективное решение - указать значение директивы date.timezone в основном конфигурационном файле php.ini. Это действие задаёт временную зону для всех выполняемых скриптов, если только она не переопределяется позднее программно.

Пошаговая инструкция:

  1. Определите местоположение php.ini. Выполните скрипт с вызовом phpinfo() и найдите строку Loaded Configuration File. Например, /etc/php/8.1/cli/php.ini для CLI или /etc/php/8.1/apache2/php.ini для веб-сервера.
  2. Отредактируйте файл. Найдите строку ;date.timezone = (она обычно закомментирована). Раскомментируйте её и укажите корректную временную зону, например:
    date.timezone = Europe/Moscow

    Php выделить память (выделение памяти php)

  3. Сохраните изменения и перезапустите веб-сервер (например, sudo systemctl restart apache2 или sudo systemctl restart php8.1-fpm).
  4. Проверьте. Создайте файл test.php с кодом:
    <?php
    echo date_default_timezone_get();
    echo "\n";
    echo date('Y-m-d H:i:s');
    ?>

    Php ini timezone (настройка часового пояса в php (date.timezone))

    Результат должен показать установленную зону и правильное местное время.
    Europe/Moscow
    2025-03-29 14:35:12

    Xampp php ini (настройка php.ini в xampp)

Типичные ошибки:

  • Директива не раскомментирована - PHP будет использовать значение по умолчанию (обычно UTC) и генерировать предупреждение Warning: date.timezone not set.
  • Неверный формат зоны - используйте полные идентификаторы из списка IANA (например, America/New_York), сокращения вроде MSK недопустимы.
  • После изменения php.ini не перезагружен сервер - изменения вступают в силу только после перезапуска.

Как установить часовой пояс для одного скрипта без изменения php.ini?

Функция date_default_timezone_set() позволяет задать временную зону непосредственно в коде. Это удобно, когда доступ к php.ini ограничен (например, на общем хостинге) или для разных частей приложения нужны разные зоны.

<?php
date_default_timezone_set('Asia/Vladivostok');
echo date_default_timezone_get(); // Asia/Vladivostok
echo date('Y-m-d H:i:s');
?>

Php ini sessions (настройка сессий в php (session.*))

Проблемы: вызов функции должен произойти до любых операций с датами. Если настройка сделана после вызова date(), зона не применится к уже отработавшим функциям. Также эта установка действует только в рамках текущего запроса.

Как задать часовой пояс для каталога через .htaccess или .user.ini?

В окружении Apache можно использовать .htaccess, если сервер разрешает php_value:

php_value date.timezone Europe/Kiev

Php ini extension (настройка расширений php (extension_dir, extension))

Для PHP-FPM или CGI поддерживается файл .user.ini в корневой директории сайта:

date.timezone = America/Chicago

ограничение памяти php (ограничение памяти php)

Эти способы меняют зону для всех скриптов в конкретном каталоге и его подкаталогах, не затрагивая глобальную конфигурацию.

Типичная ошибка: использование php_value в .htaccess при работе с PHP-FPM не сработает, нужен .user.ini или переопределение через пул FPM.

Можно ли изменить часовой пояс прямо в коде с помощью ini_set?

Да, функция ini_set() позволяет изменить значение date.timezone на время выполнения скрипта. Это альтернатива date_default_timezone_set():

<?php
ini_set('date.timezone', 'Asia/Yekaterinburg');
echo date('Y-m-d H:i:s');
?>

изменить настройки php (изменение настроек php)

Важно: метод работает только с опциями, помеченными как PHP_INI_ALL в документации. date.timezone относится к PHP_INI_ALL, поэтому изменение допустимо.

Не все хостинг-окружения разрешают динамическое изменение через ini_set - может потребоваться включение директивы allow_url_include (не рекомендуется) или других настроек.

Как передать часовой пояс при запуске PHP из командной строки?

При вызове CLI-скрипта можно задать зону через переменную окружения TZ:

TZ='Asia/Tokyo' php -r 'echo date("Y-m-d H:i:s");'

Index php page info (страница phpinfo())

Или указать кастомный ini-файл с помощью опции -c:

php -c /path/to/custom_php.ini script.php

Php ini memory (настройка memory_limit в php)

Также можно использовать опцию -d для прямой передачи:

php -d date.timezone=Australia/Sydney test.php

Этот вариант полезен для автоматизированных задач, cron-скриптов, где нужно быстро переключить зону без изменения глобальной конфигурации.

Без явной установки TZ или опции -d PHP использует значение из php.ini (или системную зону при стандартной компиляции).

- Php ini linux (настройка php.ini в linux/ubuntu)
- Php ini upload (настройка загрузки файлов в php (upload_max_filesize, post_max_size))
- Change php (изменение php)

Расширенные примеры работы с часовыми поясами в PHP

Пример 1. Получение полного списка поддерживаемых временных зон

Для выбора корректного идентификатора можно вывести все зоны, сгруппированные по регионам:

Пример
<?php
$timezones = DateTimeZone::listIdentifiers();
foreach ($timezones as $tz) {
    echo $tz . PHP_EOL;
}
?>
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
...
Europe/Moscow
Europe/Volgograd
...

Или только зоны определённого региона (например, Европа):

Пример
<?php
$europeZones = DateTimeZone::listIdentifiers(DateTimeZone::EUROPE);
print_r($europeZones);
?>
Array
(
    [0] => Europe/Amsterdam
    [1] => Europe/Andorra
    [2] => Europe/Astrakhan
    ...
)

Пример 2. Сравнение времени в разных поясах

Создание объекта DateTime для одной временной метки в двух зонах:

Пример
<?php
$utc = new DateTime('2025-10-01 12:00:00', new DateTimeZone('UTC'));
echo 'UTC: ' . $utc->format('Y-m-d H:i:s') . PHP_EOL;

$moscow = clone $utc;
$moscow->setTimezone(new DateTimeZone('Europe/Moscow'));
echo 'Moscow: ' . $moscow->format('Y-m-d H:i:s') . PHP_EOL;

$newyork = clone $utc;
$newyork->setTimezone(new DateTimeZone('America/New_York'));
echo 'New York: ' . $newyork->format('Y-m-d H:i:s') . PHP_EOL;
?>
UTC: 2025-10-01 12:00:00
Moscow: 2025-10-01 15:00:00
New York: 2025-10-01 08:00:00

Пример 3. Преобразование времени базы данных с учётом пояса

Часто в БД хранят время в UTC, а отображают в локальном поясе пользователя. Функция для преобразования:

Пример
<?php
function convertToTimezone(string $datetimeUTC, string $targetTimezone): string {
    $date = new DateTime($datetimeUTC, new DateTimeZone('UTC'));
    $date->setTimezone(new DateTimeZone($targetTimezone));
    return $date->format('Y-m-d H:i:s');
}

echo convertToTimezone('2025-12-25 23:00:00', 'Asia/Kamchatka');
?>
2025-12-26 11:00:00

Пример 4. Обработка перехода на летнее время

PHP автоматически учитывает летнее время, если используется полный идентификатор. Пример для зоны с DST:

Пример
<?php
$tz = new DateTimeZone('Europe/London');
$winter = new DateTime('2025-01-15', $tz);
$summer = new DateTime('2025-07-15', $tz);
echo 'Winter offset: ' . $tz->getOffset($winter) . ' seconds' . PHP_EOL;
echo 'Summer offset: ' . $tz->getOffset($summer) . ' seconds' . PHP_EOL;
?>
Winter offset: 0 seconds
Summer offset: 3600 seconds

То есть зимой London в UTC+0, летом в UTC+1.

Пример 5. Использование в популярных фреймворках

Laravel - зона задаётся в config/app.php:

Пример
'timezone' => 'Europe/Minsk',

Symfony - в config/packages/framework.yaml:

Пример
framework:
    default_locale: '%locale%'
    timezone: 'Europe/Paris'

Эти настройки влияют на все операции с датами внутри фреймворка.

Пример 6. Определение зоны по смещению (например, для пользователя)

Если от клиента приходит смещение в минутах от UTC, можно приблизительно определить зону (не всегда точно):

Пример
<?php
$offsetMinutes = 180; // UTC+3  (например, Москва зимой)
$timezoneName = timezone_name_from_abbr('', $offsetMinutes * 60, 0);
echo $timezoneName; // может выдать Europe/Moscow или другое
?>
Europe/Moscow

Примечание: этот метод не учитывает летнее время и может быть неточным. Для критичных приложений лучше хранить полный идентификатор зоны в профиле пользователя.

Настройка часового пояса в PHP (date.timezone) - comments

En
Php ini timezone (php)