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.

Steps to set the PHP timezone:

  1. Check the active configuration file and current timezone before choosing the target runtime file.
    $ 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.

  2. Search runtime-specific configuration for timezone overrides before editing the global php.ini file.
    $ 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.

  3. Back up the target php.ini file before changing the timezone directive.
    $ 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.

  4. Set the date.timezone directive to the required timezone identifier in the target php.ini file.
    $ 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.

  5. Load the target php.ini file directly and confirm that PHP now reports the expected timezone.
    $ 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.

  6. Reload the service that serves PHP requests when the change applies to PHP-FPM or an Apache module.
    $ 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.

  7. Check that the reloaded service stayed active.
    $ systemctl is-active php8.3-fpm
    active

    Use the matching Apache unit when the site runs as an Apache module instead of PHP-FPM.

  8. Create a temporary probe file in the document root when the application runs through a web-facing SAPI that differs from the CLI binary.
    $ 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.

  9. Request the probe URL and confirm that the served runtime returns the expected timezone.
    $ 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.

  10. Remove the temporary probe file immediately after the check.
    $ sudo rm /var/www/example.com/public/timezone-check.php

    Leaving the probe reachable exposes runtime details that should not remain available over HTTP.