I have created a cakephp 5 app with a mysql database running in UTC time. I want all datetime fields in the database in UTC. But the user resides in the timezone Europe/Paris. So I show all datetime values via the i18nFormat function in Europe/Paris time. When I show a form, all values in datetime fields should be shown in Europe/Paris time and that works. But when the user enters a datetime value in a form then that value is interpreted as UTC and stored in the database as is and so shows up in the same form the next time 2 hours later. Also when a datetime field ‘plandate’ is set to 10 AM UTC and I perform a $entity->date=$entity->plandate then $entity->date is set to 12 AM UTC. It looks like the datetime values in an entity are converted to Europe/Paris timezone but on assignment to another field are interpreted as UTC.

This is my app_local configuration file (only the relevant lines):

<?php
use Cake\Database\TypeFactory;
TypeFactory::build('datetime')->setUserTimezone('Europe/Paris');
return [
    'Datasources' => [
        'default' => [
            'timezone' => 'UTC',
        ],
    ],
    'App' => [
        'namespace' => 'App',
        'encoding' => env('APP_ENCODING', 'UTF-8'),
        'defaultLocale' => env('APP_DEFAULT_LOCALE', 'de_DE'),
        'defaultTimezone' => 'Europe/Paris',
        'base' => false,
        'dir' => 'src',
        'webroot' => 'webroot',
        'wwwRoot' => WWW_ROOT,
        'fullBaseUrl' => false,
        'imageBaseUrl' => 'img/',
        'cssBaseUrl' => 'css/',
        'jsBaseUrl' => 'js/',
        'paths' => [
            'plugins' => [ROOT . DS . 'plugins' . DS],
            'templates' => [ROOT . DS . 'templates' . DS],
            'locales' => [RESOURCES . 'locales' . DS],
        ],
    ],
    'Time' => ['userTimezone' => 'Europe/Paris'],
    'Session' => ['timeout' => 120, 'ini' => ['session.cookie_lifetime' => 7500]]
];
?>

To sum up: When I show a form, the UTC times from the database are correctly converted into Europe/Paris time. But when the user enters a local time it is interpreted as UTC and written directly without conversion to the database.
In order to correct the problem I am already doing things like:
$lesson = $this->Lessons->patchEntity($lesson, $this->request->getData());
$plandate = new DateTime($this->request->getData(‘plandate’), ‘Europe/Paris’);
$lesson->plandate = $plandate->setTimezone(‘UTC’);
$this->Lessons->save($lesson)

That works but is of course not a satisfying solution.
What am I doing wrong and what would be the correct configuration?

Help is much appreciated!

My config/app.php has:

$timezone = 'America/Toronto';

at the top (could easily come from .env instead of being hard-coded), then in the config array returned:

'App' => [
    'timezone' => [
        'name' => $timezone,
    ],
],
'Datasources' => [
    'default' => [
        'timezone' => $timezone,
    ],
],

And my config/bootstrap.php has:

date_default_timezone_set(Configure::read('App.timezone.name'));
1 Like