Bug or not? Set timezone in CakePHP 4.x app.php or .env not working

Hi all,

Not very sure if it’s a bug or not. I try to change my default timezone in app.php like this:

return [
    ...
    'App' => [
        'namespace' => 'App',
        'encoding' => env('APP_ENCODING', 'UTF-8'),
        'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
        'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Europe/Brussels'), // <= this rule has been changed
        'base' => false,
        'dir' => 'src',
        'webroot' => 'webroot',
        'wwwRoot' => WWW_ROOT,
        //'baseUrl' => env('SCRIPT_NAME'),
        'fullBaseUrl' => false,
        'imageBaseUrl' => 'img/',
        'cssBaseUrl' => 'css/',
        'jsBaseUrl' => 'js/',
        'paths' => [
            'plugins' => [ROOT . DS . 'plugins' . DS],
            'templates' => [ROOT . DS . 'templates' . DS],
            'locales' => [RESOURCES . 'locales' . DS],
        ],
    ],
	...
];

With this setting, when I debug this code:

debug(date('Y-m-d H:i:s'));
debug(FrozenTime::now());

I still got these values:

ROOT\plugins\Blog\src\Controller\ArticlesController.php (line 44)
'2022-08-15 17:52:32'

ROOT\plugins\Blog\src\Controller\ArticlesController.php (line 45)
object(Cake\I18n\FrozenTime) id:0 {
	'time' => '2022-08-15 17:52:32.791773+00:00'
	'timezone' => 'UTC'
	'fixedNowTime' => false
}

The time is still 2 hours behind my own time zone (Europe/Brussels) and as you can see, the timezone is still ‘UTC’.

I also tried to change the .env file:

export APP_NAME="cms"
export DEBUG="true"

export APP_ENCODING="UTF-8"
export APP_DEFAULT_LOCALE="en_US"
export APP_DEFAULT_TIMEZONE="Europe/Brussels" // <= this rule has been changed

But with this code, the timezone is still ‘UTC’. Even after I cleared the cache…

Do you think this is a bug? The only thing that helps is to change the initialize method in AppController.php like this:

public function initialize(): void
{
	parent::initialize();

	date_default_timezone_set('Europe/Brussels'); // <= this rule has been added
}

But this is not the way I want it to work :slight_smile:

Any idea(s)?
Thanks!

your mentioned fix via adding date_default_timezone_set() is already present in the default bootstrap.php

Which as you can see uses the value of your App.defaultTimezone config.

I would personally check if env('APP_DEFAULT_TIMEZONE', 'Europe/Brussels') inside your app.php returns the value you expect (so the one inside your config/.env file, otherwise the default value 'Europe/Brussels')

If this is correct but your timezone still gets messed up then maybe you overwrote the App.defaultZimezone inside your app_local.php or maybe a plugin you are using.

Thanks for you reply, Kevin!

I would personally check if env('APP_DEFAULT_TIMEZONE', 'Europe/Brussels') inside your app.php returns the value you expect (so the one inside your config/.env file, otherwise the default value 'Europe/Brussels' )

Well, that’s indeed one thing I tried but the problem still exists. This is my current config.env file (it’s been a copy from \config.env.example):

#!/usr/bin/env bash
# Used as a default to seed config/.env which
# enables you to use environment variables to configure
# the aspects of your application that vary by
# environment.
#
# Having this file in production is considered a **SECURITY RISK** and also decreases
# the boostrap performance of your application.
#
# To use this file, first copy it into `config/.env`. Also ensure the related
# code block for loading this file is uncommented in `config/boostrap.php`
#
# In development .env files are parsed by PHP
# and set into the environment. This provides a simpler
# development workflow over standard environment variables.
export APP_NAME="cms"
export DEBUG="true"
export APP_ENCODING="UTF-8"
export APP_DEFAULT_LOCALE="en_US"
export APP_DEFAULT_TIMEZONE="Europe/Brussels"
export SECURITY_SALT="ydufwt98d7cz5iexeksmocdnq3g50e58yh4ph203fl1y5s2q2xzljtkjmuqrqx6z"

# Uncomment these to define cache configuration via environment variables.
#export CACHE_DURATION="+2 minutes"
#export CACHE_DEFAULT_URL="file://tmp/cache/?prefix=${APP_NAME}_default&duration=${CACHE_DURATION}"
#export CACHE_CAKECORE_URL="file://tmp/cache/persistent?prefix=${APP_NAME}_cake_core&serialize=true&duration=${CACHE_DURATION}"
#export CACHE_CAKEMODEL_URL="file://tmp/cache/models?prefix=${APP_NAME}_cake_model&serialize=true&duration=${CACHE_DURATION}"

# Uncomment these to define email transport configuration via environment variables.
#export EMAIL_TRANSPORT_DEFAULT_URL=""

# Uncomment these to define database configuration via environment variables.
export DATABASE_URL="mysql://root:@localhost/${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true&quoteIdentifiers=false&persistent=false"
#export DATABASE_TEST_URL="mysql://my_app:secret@localhost/test_${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true&quoteIdentifiers=false&persistent=false"

# Uncomment these to define logging configuration via environment variables.
#export LOG_DEBUG_URL="file://logs/?levels[]=notice&levels[]=info&levels[]=debug&file=debug"
#export LOG_ERROR_URL="file://logs/?levels[]=warning&levels[]=error&levels[]=critical&levels[]=alert&levels[]=emergency&file=error"

When I check the ‘APP_DEFAULT_TIMEZONE’ variable AppController.php, I still got ‘UTC’ echoed instead of ‘Europe/Brussels’.
Even when I change ‘DEBUG’ to ‘false’ or change the ‘APP_NAME’, the initial values are printed.

It looks like my application ignores the .env file completely, but I don’t know where it gets the environment values :face_with_raised_eyebrow:

Have you actually added the code to read the .env file? It doesn’t happen automatically.

Thanks for your feedback too, Zuluru!

As discribed here and here, I already added ‘josegonzalez/dotenv’ to composer.json:

{
    "name": "cakephp/app",
    "description": "CakePHP skeleton app",
    "homepage": "https://cakephp.org",
    "type": "project",
    "license": "MIT",
    "require": {
        "php": ">=7.2",
        "cakephp/authentication": "^2.0",
        "cakephp/cakephp": "^4.3",
        "cakephp/migrations": "^3.2",
        "cakephp/plugin-installer": "^1.3",
        "intervention/image": "^2.7",
        "mobiledetect/mobiledetectlib": "^2.8"
    },
    "require-dev": {
        "cakephp/bake": "^2.6",
        "cakephp/repl": "^0.1",
        "cakephp/cakephp-codesniffer": "^4.5",
        "cakephp/debug_kit": "^4.5",
        "josegonzalez/dotenv": "^3.2",
        "phpunit/phpunit": "~8.5.0 || ^9.3"
    },
...

I also removed the .env functionality in bootstrap.php:

...
/*
 * See https://github.com/josegonzalez/php-dotenv for API details.
 *
 * Uncomment block of code below if you want to use `.env` file during development.
 * You should copy `config/.env.example` to `config/.env` and set/modify the
 * variables as required.
 *
 * The purpose of the .env file is to emulate the presence of the environment
 * variables like they would be present in production.
 *
 * If you use .env files, be careful to not commit them to source control to avoid
 * security risks. See https://github.com/josegonzalez/php-dotenv#general-security-information
 * for more information for recommended practices.
*/
if (!env('APP_NAME') && file_exists(CONFIG . '.env')) {
    $dotenv = new \josegonzalez\Dotenv\Loader([CONFIG . '.env']);
    $dotenv->parse()
        ->putenv()
        ->toEnv()
        ->toServer();
}
...

But it seems that this ‘if’ returns false. It looks like there IS already an ‘APP_NAME’ declared. I have no clue where, I can’t find it anywhere in my project. I’ll check if there’s an environment variable in XAMPP or something. If not: I’m out of options :sweat_smile:

OK, I’m finally there. I found out that it was necessary to only restart the local application server. Before, I constantly restarted XAMPP and my browser instead. Kinda stupid if I realize now :upside_down_face:

So final conclusion: it was not a bug :wink:
Thanks for your feedback Kevin and Zuluru, it helped me discover the problem!

I have no experience with XAMPP but back in the day I only remember, that there was a window which lets you start your services like httpd and mysql.

Just closing and re-opening the XAMPP management won’t restart the services as far as I can tell, so thats the issue you ran into.