Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як налаштувати часовий пояс у контейнері з Laravel, щоб дати не з'їжджали?

У контейнері з PHP кілька незалежних годинників і налаштувань часового поясу:

Рівень Де задається На що впливає
ОС контейнера TZ, /etc/localtime, пакет tzdata date у shell, cron, логи системних утиліт
PHP date.timezone у php.ini date(), new DateTime() без явного поясу
Laravel config/app.php → timezone now(), Carbon, Eloquent-дати, планувальник
база даних налаштування сервера, сесії NOW(), CURRENT_TIMESTAMP, timestamptz

Типові пастки:

  • офіційні PHP-образи за замовчуванням - UTC, і date.timezone не задано;
  • Alpine без tzdata взагалі не знає назв поясів - TZ=Europe/Kyiv мовчки ігнорується;
  • TZ не впливає на PHP напряму: PHP бере пояс з date.timezone, а якщо його немає - з власного значення за замовчуванням (UTC). Деякі сервери (зокрема вбудований у FrankenPHP) не підхоплюють TZ для PHP-дат;
  • Laravel перевизначає PHP: при старті він викликає date_default_timezone_set(config('app.timezone')), тож у застосунку діє саме конфігурація Laravel, а cron-задачі ОС чи сторонні скрипти - живуть за іншими правилами.

Узгоджене налаштування:

RUN apk add --no-cache tzdata        # для Alpine
ENV TZ=Europe/Kyiv
RUN echo "date.timezone=\${TZ}" > "$PHP_INI_DIR/conf.d/timezone.ini"
// config/app.php
'timezone' => env('APP_TIMEZONE', 'UTC'),

Яку політику обрати:

  • зберігати в базі UTC (або timestamptz у PostgreSQL) - класична рекомендація: без двозначностей при переході на літній час, без проблем з користувачами з різних поясів;
  • показувати в локальному поясі користувача чи сайту на рівні відображення;
  • якщо застосунок свідомо працює в одному місцевому поясі (сайт для однієї країни), - той самий пояс на всіх рівнях: ОС, PHP, Laravel, планувальник. Розбіжність між рівнями - головне джерело зсуву на 2-3 години.

Планувальник: ->dailyAt('09:00') виконується за поясом app.timezone (чи schedule_timezone), а не ОС. Переходи на літній час можуть пропустити чи подвоїти задачі, заплановані на 3:00 ночі.

Перевірка в контейнері:

docker exec app date
docker exec app php -r 'echo date_default_timezone_get(), PHP_EOL;'
docker exec app php artisan tinker --execute 'echo now();'

Докладніше в документації: PHP: налаштування date.timezone

Схожі питання