Setting the correct PHP timezone keeps log timestamps, scheduled jobs, cache expiry, and generated dates aligned with the same local time reference. When the runtime falls back to the wrong zone, incident timelines drift, queued work appears late or early, and application output stops matching the system or database clocks it is compared against.
PHP resolves its default timezone from the runtime that executes the request. Code that calls date_default_timezone_set() overrides the runtime value for that request, otherwise the loaded date.timezone directive is used, and UTC is used when no valid timezone is available. The important operational detail is that CLI, PHP-FPM, and Apache module runtimes can each load a different php.ini and additional .ini files, so the active SAPI has to be identified before editing anything.
A full Region/City identifier such as Asia/Kuala_Lumpur keeps daylight-saving and historical offset data consistent, while invalid date.timezone values trigger a startup warning and fall back to UTC. Examples below use common package-managed Linux paths, but the same flow applies on other platforms once the loaded configuration file, override layers, and served runtime are confirmed.
Related: How to check PHP version
$ php --ini
Configuration File (php.ini) Path: /etc/php/8.3/cli
Loaded Configuration File: /etc/php/8.3/cli/php.ini
Scan for additional .ini files in: /etc/php/8.3/cli/conf.d
Additional .ini files parsed: /etc/php/8.3/cli/conf.d/10-opcache.ini,
/etc/php/8.3/cli/conf.d/10-pdo.ini,
##### snipped #####
$ php --ri date | grep -E 'Default timezone|date.timezone'
Default timezone => UTC
date.timezone => UTC => UTC
Package-managed Linux hosts commonly use paths such as /etc/php/8.3/cli/php.ini, /etc/php/8.3/fpm/php.ini, /etc/php/8.3/apache2/php.ini, or /etc/php.ini.
Related: How to find PHP configuration files
$ sudo grep -REn 'php_(admin_)?value\[date\.timezone\]' /etc/php/8.3/fpm/pool.d /etc/php-fpm.d /etc/apache2 /etc/httpd 2>/dev/null
No output means the common PHP-FPM and Apache configuration locations are not overriding date.timezone. On CGI or FastCGI deployments, a .user.ini file can still replace the value inside part of the application tree.
Application code that calls date_default_timezone_set() overrides the runtime default for that request.
$ sudo cp /etc/php/8.3/fpm/php.ini /etc/php/8.3/fpm/php.ini.bak-$(date +%Y%m%d%H%M%S)
Replace the sample path with the actual file reported for the CLI, PHP-FPM, or Apache runtime that needs the new default.
$ sudo vi /etc/php/8.3/fpm/php.ini [Date] date.timezone = Asia/Kuala_Lumpur
Use a full Region/City identifier from the supported timezone list instead of abbreviations such as EST or BST.
Leaving the directive empty or setting an invalid identifier makes current PHP warn and use UTC during startup.
$ php -c /etc/php/8.3/fpm/php.ini -i | grep -E 'Loaded Configuration File|Default timezone|date.timezone' Loaded Configuration File => /etc/php/8.3/fpm/php.ini Default timezone => Asia/Kuala_Lumpur date.timezone => Asia/Kuala_Lumpur => Asia/Kuala_Lumpur
Put -i after -c so the reported values come from the file being tested instead of the default CLI configuration.
$ sudo systemctl reload php8.3-fpm
Reload Apache instead with sudo systemctl reload apache2 when PHP runs as an Apache module. No service reload is required for a CLI-only change because new CLI processes read the updated php.ini automatically.
$ systemctl is-active php8.3-fpm active
Use the matching Apache unit when the site runs as an Apache module instead of PHP-FPM.
$ sudo tee /var/www/example.com/public/timezone-check.php >/dev/null <<'PHP'
<?php
header('Content-Type: text/plain');
echo date_default_timezone_get(), PHP_EOL;
PHP
Use the document root served by the same virtual host or PHP-FPM pool that handles the application.
Create the probe only for the brief verification window because it exposes runtime behavior over HTTP.
$ curl -s http://example.com/timezone-check.php Asia/Kuala_Lumpur
The response confirms the default timezone seen by the served runtime, not just the CLI binary. Replace the URL with the target site.
$ sudo rm /var/www/example.com/public/timezone-check.php
Leaving the probe reachable exposes runtime details that should not remain available over HTTP.