It is important to set the default time zone for date/time management.
Usually, when we refer to date/time, do not pay attention to which time zone value is being referred to.
For example, if we live in Rome and want to spend our next holiday in New York, when we receive the check-in date/time from the hotel, we must consider which time zone time is being referred to (whether local or remote).
When we display a date/time value that could be misunderstood, it is always recommended to add a time zone reference to it. The time zone is expressed through positive or negative hours compared to a reference that is usually GMT (Greenwich Mean Time).
For example, if it is 9 p.m. in Rome (GMT +1), in GMT time it will be 8 p.m. (GMT +0), 3 p.m. in New York (GMT -5), and finally 12 p.m. in Los Angeles (GMT -8).
Therefore, it is necessary to establish a common shared time value. For this purpose, it is advisable to use GMT as the time reference for all values and operations on values.
We need to configure the time zone in two environments:
timeZone
attribute of a configuration; this will set the default time zone for all functions about the date and timeComplete the first step. Open basic/config/web.php
and add the timeZone
property with the GMT
value in the config
array, for example, after the basePath
property:
'timeZone' => 'GMT',
The second step is setting the time zone for the database connections, if the database, such as MySQL, does not provide it. This is done globally by adding this code in the on afterOpen
event. Open basic/config/db.php
and append it as the last attribute in an array (usually the last attribute is charset
):
'on afterOpen' => function($event) { $event->sender->createCommand("SET time_zone = '+00:00'")->execute(); }
This code means that once the connection with the database is opened, the SQL query SET time_zone = +00:00
will be executed for every connection that we are going to establish with the database, and every date/time field value and function related to the GMT (+00:00) time zone will be considered.
Let's make a test. Create a new controller that simply displays the current date/time and time zone, in basic/controllers/TestTimezoneController.php
with an action named actionCheck()
:
<?php namespace appcontrollers; use Yii; use yiiwebController; class TestTimezoneController extends Controller { public function actionCheck() { $dt = new DateTime(); echo 'Current date/time: '.$dt->format('Y-m-d H:i:s'); echo '<br />'; echo 'Current timezone: '.$dt->getTimezone()->getName(); echo '<br />'; } }
Point your browser to http://hostname/basic/web/test-timezone/check
. This is what my browser displayed:
Current date/time: 2015-05-27 19:53:35 Current timezone: GMT
And, the local time (in Rome) was 21:53:35, because Rome was then at +02:00 GMT due to daylight savings time.
If we comment the timeZone
property in the app configuration in basic/config/web.php
, we will see the default server time zone that is in my browser:
Current date/time: 2015-05-27 21:53:35 Current timezone: Europe/Rome
This confirms that we have changed the default timezone
property for all date/time functions. The last check to perform is on the database. Create a new action named actionCheckDatabase
to verify that the database's default time zone for the current (and every) connection is GMT:
public function actionCheckDatabase() { $result = Yii::$app->db->createCommand('SELECT NOW()')->queryColumn(); echo 'Database current date/time: '.$result[0]; }
Point your browser to http://hostname/basic/web/test-timezone/check-database
. This is what my browser displayed:
Database current date/time: 2015-05-27 20:12:08
And the local time (in Rome) was 22:12:08, because Rome was then at +02:00 GMT.
Remember that, from now on, all date/time information displayed in a database refers to the GMT time zone, although this specification was missing (as we can see in the previous database's current date/time).
Another strategy to handle the GMT time zone in a database's date/time column is to store the value as a timestamp, which is by definition an integer that indicates the number of seconds from 01/01/1970 at 00:00:00 in the GMT (UTC) time zone; so it is immediately understandable that field is a date/time with the GMT time zone, but remember that any database function applied to it will be executed using the database's default time zone.
3.135.207.129