[Yii1] Giocare Con Le Date

Ciao,

per gestire automaticamente date di creazione e aggiornamento dei record, stavo giocando con il CDateTimeParser e TIMESTAMP su mysql.

Il gioco si sta trasformando in un massacro… >:(

In un model, nella public afterFind ho scritto




$dataDaDb = date(Yii::app()->params['viewDateTimeFormat'],CDateTimeParser::parse($this->create_time, 'yyyy-MM-dd hh:mm:ss'));

$dataDaDb = date(Yii::app()->params['dbDateTimeFormat'], CDateTimeParser::parse($dataDaDb, 'dd/MM/yyyy hh:mm:ss'));


$dataProva = "10/06/2014 15:28:57";

$dataProva = date(Yii::app()->params['dbDateTimeFormat'], CDateTimeParser::parse($dataProva, 'dd/MM/yyyy hh:mm:ss'));


$this->create_time = 'data nel db:'.$this->create_time.

                     ' dataDaDb convertita:'.$dataDaDb.

                     ' dataProva convertita:'. $dataProva;



come risultato ottengo:


data nel db: 2014-06-10 15:28:57

dataDaDb convertita: 1970-01-01 01:00:00 

dataProva convertita: 2014-06-10 15:28:57

Perché se passo la variabile $this->create_time il parser non la digerisce???

semplifico il codice per vedere se mi aiutate!




$data_nel_db = $this->create_time;

$data_nel_db_parsed = CDateTimeParser::parse($data_nel_db, 'yyyy-MM-dd hh:mm:ss');

$data_nel_db_per_visualizzazione = date('d/m/Y  H:i:s',$data_nel_db_parsed);

$data_nel_db_per_visualizzazione_parsed = CDateTimeParser::parse($data_nel_db_per_visualizzazione, 'dd/MM/yyyy hh:mm:ss');

$prova_parser = CDateTimeParser::parse('10/06/2014 15:28:57', 'dd/MM/yyyy hh:mm:ss');



output:




data nel db: 2014-06-10 15:28:57

data_nel_db_parsed: 1402406937

data_nel_db_per_visualizzazione: 10/06/2014 15:28:57

data_nel_db_per_visualizzazione_parsed: 

prova_parser: 1402406937



C’è uno spazio di troppo nella terza riga, dove definisci il pattern: “d/m/Y H:i:s”.

Togli uno spazio in modo che sia così "d/m/Y H:i:s" e funziona.

Ciao

SomethingWicked santo subito! :D

Ahah esagerato :D

Salve, sto imparando Yii da 3 giorni. Avrei una (milionata) domanda:

Devo convertire manualmente come ho visto qui sopra le date in ogni Model o esiste un modo per dire (tipo nel config/main.php) qual’è il formato di output desiderato?

grazie

Prova a leggere qui per avere un’idea: http://www.yiiframework.com/wiki/564/i18n-all-in-one-format-and-timezone-conversions-for-date-time-timestamp-and-datetime/.

Operativamente quando si vuole far sì che più model/controller utilizzino gli stessi strumenti, per evitare ridondanza, si estende con un component, o un approccio simile.

Seguendo la guida linkata ho creato un component CActiveRecordDateTime ed esteso CActiveRecord

Pare funzioni tutto!

Grazie ancora!

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?