How to handle user's timezone and UTC sync between application and database in CakePHP?

天大地大妈咪最大 提交于 2019-12-08 00:48:00

问题


I need to display dates and times in user's timezone. But I also need to save dates and times in UTC, so my database stay consistent.

My cakephp application configured like this:

In config/app.php file:

 'Datasources' => [
    'default' => [
        ...
        'timezone' => 'UTC',

In config/bootstrap.php file:

/*
 * Set server timezone to UTC. You can change it to another timezone of your
 * choice but using UTC makes time calculations / conversions easier.
 */
date_default_timezone_set('UTC');

In my application, a user can change his timezone whenever he wants. It's then saved in database and available as $this->Account->timezone in controllers, and $account->timezone in views.

So let's say my database is consistent and all my datetimes are stored in UTC, so when user type in a date, it's converted to UTC (from his timezone).

Now I want to display these dates. I get them from my database in UTC. For now I use the method from Cakephp (where $item is an entity and date is an attribute of this entity):

$item->date->i18nFormat('dd/MM',$user->timezone),

With this function I can easily display datetimes in the format I want, and in the timezone I want.

Is there a way to set $user->timezone to the entire app, so I don't need to specify it each time ?

Thanks.


回答1:


Your question reads as if you're already handling the timezone conversion when saving user supplied dates, so I'll stick to the display part.

Use the time helper

As stated in the comments, there's nothing wrong with explicitly passing the timezone whenever it is required, however if you'd really need to adjust the timezone for (mostly) everything you output in your view templates, then take a look at the (kind of undocumented) time helper's outputTimezone option.

$this->loadHelper('Time', ['outputTimezone' => $user->timezone]);

Then use the helper's i18nFormat() method and you should be good with regards to timezone conversion:

$this->Time->i18nFormat($item->date, 'dd/MM');

Configure a global string format

It's also possible to globally configure the output format via the \Cake\I18n\DateFormatTrait::setToStringFormat() and \Cake\Chronos\Traits\FormattingTrait::setToStringFormat() methods, which are available on the Date/Time/FrozenDate/FrozenTime/Chronos classes accordingly.

The following would for example cause all "date only" objects to be formatted as dd/MM when being converted to a string, being it through implicit casting, or explicit formatting when calling for example i18nFormat() without passing a specific format:

\Cake\I18n\Date::setToStringFormat('dd/MM');

See also

  • Cookbook > Views > Helpers > Configuring Helpers
  • Cookbook > Date & Time > Setting the Default Locale and Format String


来源:https://stackoverflow.com/questions/49280448/how-to-handle-users-timezone-and-utc-sync-between-application-and-database-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!