Spiego meglio
dentro la cartella /protected/components ho creato un file
CActiveRecordDateTime.php
con dentro il codice del model (leggermente aggiustato pe la località) trovato alla pagina linkata sopra:
<?php
class CActiveRecordDateTime extends CActiveRecord
{
// User's timezone
public $user_timezone = 'Europe/Rome';
/*** PHP FUNCTION FORMATS ***/
// Between PHP and User *** ISO RESULT ***
public $php_user_short_date = 'd/m/Y'; // dd/mm/yyyy
public $php_user_time = 'H:i:s'; // HH:mm:ss
public $php_user_datetime = 'd/m/Y H:i:s'; // dd/mm/yyyy HH:mm:ss
// Between PHP and Db (MySql)
public $php_db_date = 'Y-m-d'; // yyyy-mm-dd
public $php_db_time = 'H:i:s'; // HH:mm:ss
public $php_db_datetime = 'Y-m-d H:i:s'; // yyyy-mm-dd HH:mm:ss
protected function afterFind()
{
foreach($this->metadata->tableSchema->columns as $columnName => $column)
{
/* Test if current column is date/time/timestamp/datetime */
if (($column->dbType == 'date') ||
($column->dbType == 'time') ||
($column->dbType == 'timestamp')||
($column->dbType == 'datetime'))
{
/* Test for null column */
if($this->$columnName === null){
$test = 0;
}
else{
$test = str_replace(array('/','-', '.', ':', ' '),'',
$this->$columnName);
}
/* Continue if column is not null, else set column to false -
which will prevent column being displayed in gridviews if
gridview data is set like:
'value' => '($data->mycolumn) ? $data->mycolumn : "" ',
*/
if($test > 0)
{
/* Create a new php DateTime object using the
date/time/timestamp/datetime retrieved from the
database.
Set the object's timezone to UTC (same as the
server's timezone) */
$datetime_object = new
DateTime($this->$columnName,
new DateTimeZone('UTC') );
/* Change the DateTime object's timezone
and format, based on the column's data
type in the DB.
Note: changing the object's timezone will
automatically also change its time. */
switch ($column->dbType)
{
case 'date':
/* Convert the object's time to the user's time */
// Do not take any action here. Date columns do
// not include the time and thus cannot be
// converted.
/* Output the required format */
$this->$columnName =
$datetime_object->format(
$this->php_user_short_date);
break;
case 'time':
/* Convert the object's time to the user's time */
$datetime_object->setTimeZone(new
DateTimeZone($this->user_timezone));
/* Output the required format */
$this->$columnName =
$datetime_object->format($this->php_user_time);
break;
case 'timestamp':
/* Convert the object's time to the user's time */
$datetime_object->setTimeZone(new
DateTimeZone($this->user_timezone));
/* Output the required format */
$this->$columnName =
$datetime_object->format(
$this->php_user_datetime);
break;
case 'datetime':
/* Convert the object's time to the user's time */
$datetime_object->setTimeZone(new
DateTimeZone($this->user_timezone));
/* Output the required format */
$this->$columnName =
$datetime_object->format(
$this->php_user_datetime);
break;
}
}
else{
$this->$columnName = false;
}
}
}
return parent::afterFind();
}
protected function beforeSave()
{
/* Reformat date/time/timestamp/datetime from local format and timezone
to database format and UTC. */
foreach($this->metadata->tableSchema->columns as $columnName => $column)
{
/* Test if current column is date/time/timestamp/datetime */
if (($column->dbType == 'date') ||
($column->dbType == 'time') ||
($column->dbType == 'timestamp')||
($column->dbType == 'datetime'))
{
/* Test for null column */
if($this->$columnName === null){
$test = 0;
}
else{
$test = str_replace(array('/','-', '.', ':', ' '),'',
$this->$columnName);
}
/* Continue if column is not null. */
if($test > 0)
{
switch ($column->dbType)
{
case 'date':
/* create datetime object */
$datetime_object = DateTime::createFromFormat(
$this->php_user_short_date,
$this->$columnName,
new DateTimeZone($this->user_timezone));
/* change timezone to UTC */
// Do not take any action. Do not convert the
// timezone for dates, because the time is not
// included in the data saved to the db, which
// means that the data cannot be converted back.
/* change format to DB format */
$this->$columnName =
$datetime_object->format($this->php_db_date);
break;
case 'time':
/* create datetime object */
$datetime_object = DateTime::createFromFormat(
$this->php_user_time,
$this->$columnName,
new DateTimeZone($this->user_timezone));
/* change timezone to UTC */
$datetime_object->setTimeZone(new
DateTimeZone('UTC'));
/* change format to DB format */
$this->$columnName =
$datetime_object->format($this->php_db_time);
break;
case 'timestamp':
/* create datetime object from user's format */
$datetime_object = DateTime::createFromFormat(
$this->php_user_datetime,
$this->$columnName,
new DateTimeZone($this->user_timezone));
/* change timezone to UTC */
$datetime_object->setTimeZone(new
DateTimeZone('UTC'));
/* change format to DB format */
$this->$columnName =
$datetime_object->format($this->php_db_datetime);
break;
case 'datetime':
/* create datetime object */
$datetime_object = DateTime::createFromFormat(
$this->php_user_datetime,
$this->$columnName,
new DateTimeZone($this->user_timezone));
/* change timezone to UTC */
$datetime_object->setTimeZone(new
DateTimeZone('UTC'));
/* change format to DB format */
$this->$columnName =
$datetime_object->format($this->php_db_datetime);
break;
}
}
}
}
return parent::beforeSave();
}
}
?>
nel file
/protected/config/main.php
ho fatto le due modifiche suggerite a timezone e inizializzazione db:
return array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'name'=>'nome applicazione',
'theme'=>'theme',
'sourceLanguage'=>'en',
'language'=>'it',
'timeZone'=>'GMT',
...
...
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=mydbname',
'emulatePrepare' => true,
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
'enableParamLogging' => true,
'initSQLs'=>array("set time_zone='+00:00';"),
a questo punto nei model occorre estendere la nuova classe ad esempio
class MioModello extends CActiveRecordDateTime
usando nella view
MioModello->miaData
otterremo a video la data nel formato desiderato e indicato in
// Between PHP and User *** ISO RESULT ***
public $php_user_short_date = 'd/m/Y'; // dd/mm/yyyy
public $php_user_time = 'H:i:s'; // HH:mm:ss
public $php_user_datetime = 'd/m/Y H:i:s'; // dd/mm/yyyy HH:mm:ss
a seconda del tipo di campo del database.
Quando si vuole inserire una data nel database, deve essere inviata sempre in uno dei tre formati che si usano a video.
A me funziona tutto correttamente, ma qualcuno conferma che è un modo corretto di agire?