open-how2 – Entdecke. Verstehe. Nutze.
Veröffentlicht am
How2-Tipps

PHP-Zeit & Zeitzone korrekt einstellen – inkl. Troubleshooting (Apache/Nginx, PHP-FPM, Frameworks & DB)

Autor
PHP-Zeit & Zeitzone korrekt einstellen – inkl. Troubleshooting (Apache/Nginx, PHP-FPM, Frameworks & DB)

Die richtige Zeitzone ist für Logs, Cronjobs, Termine und Reports essenziell. In PHP gibt es mehrere Ebenen, die die Zeit beeinflussen: php.ini, PHP-FPM/Apache/Nginx, Projekt-Code/Framework, Datenbank und sogar Frontend-JavaScript. Dieser Leitfaden zeigt die saubere Grundkonfiguration – und wie du typische „Warum steht da immer noch UTC?“-Fallen findest und behebst.

1) Zielbild verstehen

  • Systemzeit: timedatectl (Linux) – wirkt auf Dienste wie Webserver, DB, Cron.
  • PHP-Laufzeit: date.timezone (php.ini) + ggf. date_default_timezone_set() im Code.
  • Webserverbindung: Richtiger FPM-Socket/Handler (z. B. php8.4-fpm.sock).
  • Framework/Code: Laravel/Symfony/WordPress/TYPO3-Einstellungen.
  • Datenbank: MySQL/MariaDB/PostgreSQL Session-/Server-TZ.
  • Frontend: JS-Formatter können UTC erzwingen.

2) Standardlösung: Zeitzone in der php.ini

Dauerhaft pro SAPI (FPM, Apache, CLI):

date.timezone = Europe/Berlin

Typische Debian/Ubuntu-Pfade:

/etc/php/8.4/fpm/php.ini       # für PHP-FPM (Web)
/etc/php/8.4/apache2/php.ini   # für mod_php (falls genutzt)
/etc/php/8.4/cli/php.ini       # für CLI/Cron

Danach Dienst neu starten:

sudo systemctl restart php8.4-fpm
sudo systemctl reload apache2   # bzw. sudo systemctl reload nginx

3) Projektbezogen (wenn keine php.ini-Zugriffe möglich)

Apache (.htaccess / vHost)

php_value date.timezone "Europe/Berlin"

Im PHP-Code (Entry-Point, z. B. public/index.php, wp-config.php)

date_default_timezone_set('Europe/Berlin');

Das im Code ist ein schneller, robuster Workaround – sollte aber nicht den Server-Fix dauerhaft ersetzen.

4) Verifizieren: Läuft die Einstellung wirklich im Web?

Lege eine Testseite an:

<?php
echo 'ini: '.ini_get('date.timezone')."<br>";
echo 'php: '.date_default_timezone_get()."<br>";
echo 'now: '.date('Y-m-d H:i:s')."<br>";
phpinfo(); // optional

Erwartung:

ini: Europe/Berlin
php: Europe/Berlin
now: 2025-10-23 17:xx:xx   (Sommerzeit = UTC+2, Winterzeit = UTC+1)

In phpinfo() müssen Loaded Configuration File und Additional .ini files parsed zur richtigen 8.4-FPM-Instanz passen.

5) Häufigste Ursache: falscher FPM-Socket/vHost-Handler

Nach PHP-Upgrades zeigen vHosts gern noch auf alte Sockets.

Apache + FPM (vHost)

SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost/"

Nginx (server/location)

fastcgi_pass unix:/run/php/php8.4-fpm.sock;

Danach:

sudo systemctl restart php8.4-fpm
sudo systemctl reload apache2   # bzw. nginx

6) Overrides finden (die dich zurück auf UTC ziehen)

Spätere ini-Dateien oder Pool-Configs gewinnen.

Suche nach allen TZ-Treffern:

grep -Rni "date.timezone" /etc/php/8.4

Typische Stellen:

  • /etc/php/8.4/fpm/conf.d/*.ini
  • /etc/php/8.4/fpm/pool.d/*.conf (z. B. php_admin_value[date.timezone] = Europe/Berlin)
  • Apache vHost / .htaccess
  • .user.ini im Webverzeichnis

Wenn irgendwo UTC auftaucht → anpassen oder auskommentieren.

7) Framework-/CMS-Einstellungen (erzwingen oft eine TZ)

Laravel (config/app.php)

'timezone' => 'Europe/Berlin',

Caches leeren:

php artisan config:clear

Symfony (config/packages/framework.yaml)

framework:
  default_timezone: 'Europe/Berlin'

WordPress Einstellungen → Allgemein → Zeitzone „Europa/Berlin“ wählen (nicht UTC+X).

TYPO3 (config/system/settings.php oder LocalConfiguration.php)

$GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'] = 'Europe/Berlin';

8) Code-Fallen: gmdate() & harte UTC

Suche nach harten UTC-Setzungen:

grep -RniE "gmdate\(|DateTimeZone\('UTC'\)|date_default_timezone_set\('UTC'|Carbon::now\('UTC'|->setTimezone\('UTC'" /var/www
  • gmdate() liefert immer UTC → durch date() ersetzen, wenn lokale Zeit gewünscht.
  • Harte DateTimeZone('UTC') entfernen/ersetzen.

9) Datenbank-Zeitzone

MySQL/MariaDB

SELECT @@global.time_zone, @@session.time_zone;
-- Sicher (ohne TZ-Tabelle):
SET time_zone = '+02:00';  -- Sommer
-- Besser (mit TZ-Daten):
SET time_zone = 'Europe/Berlin';

Dauerhaft: im App-DB-Connector nach Login setzen oder Server konfigurieren.

PostgreSQL

SHOW TIMEZONE;
SET TIME ZONE 'Europe/Berlin';
-- dauerhaft z.B.:
ALTER DATABASE deine_db SET TIMEZONE TO 'Europe/Berlin';

10) CLI & Cronjobs nicht vergessen

Für Cron zählt die CLI-SAPI:

/etc/php/8.4/cli/php.ini

Prüfen:

php -i | grep -E "Loaded Configuration|date.timezone"

Zusätzlich Systemzeit checken:

timedatectl
# → Time zone: Europe/Berlin

11) Frontend-Zeitformatierung

Bibliotheken wie moment/dayjs/Intl.DateTimeFormat können auf UTC eingestellt sein.

Beispiel lokal formatiert (ohne UTC-Zwang):

new Date().toLocaleString('de-DE', { timeZone: 'Europe/Berlin' });

Falls du bewusst UTC speichern willst, lokal nur für Anzeige umrechnen.

12) Checkliste „UTC spukt noch herum?“

  1. phpinfo() zeigt Europe/Berlin (Local & Master)? ✅
  2. vHost zeigt auf php8.4-fpm.sock? ✅
  3. Keine UTC-Overrides in conf.d, pool.d, .htaccess, .user.ini? ✅
  4. Framework-TZ gesetzt & Cache geleert? ✅
  5. Kein gmdate()/harte UTC im Code? ✅
  6. DB-Session/Server-TZ passend? ✅
  7. CLI/cron ebenfalls Europe/Berlin? ✅
  8. Frontend formatiert lokal? ✅

13) Best Practice: Robustheitsschicht im Entry-Point

Selbst mit sauberer Server-Konfiguration ist es sinnvoll, im Entry-Point der App abzusichern:

date_default_timezone_set('Europe/Berlin');

So verhinderst du, dass spätere Deploys/Module die Zeitzone heimlich ändern.

Wenn php.ini richtig gesetzt ist, aber weiterhin UTC irgendwo auftaucht, liegt es fast immer außerhalb von PHPs Grundkonfiguration: falscher FPM-Socket, späte Overrides, Framework-Settings, DB-Zeitzone, Cron/CLI oder Frontend-Formatierung. Mit der obigen Checkliste bekommst du das in wenigen Minuten sauber und konsistent – von Server bis UI.