Ctimestampbehavior Malfunctioning With Afterfind() In Model

I am using CTimeStampBehaviour for setting create_time and update_time resetting create_time with afterFind() in model, Basically I am setting the format of date to be displayed on the front end. But this does not work as create_time is sent 0000-00-00 00:00:00 on using model’s afterFind(). It works fine when I comment afterFind() in model.

I have used this function in my model:




public function behaviors(){

return array(

    'CTimestampBehavior' => array(

        'class' => 'zii.behaviors.CTimestampBehavior',

        'createAttribute' => 'create_time',

        'updateAttribute' => 'update_time',

        'setUpdateOnCreate'=> true,

    )

);

}



I have seen the documentation on CTimeStampBehavior class on yii site, it has a reference to afterFind() inheritence but does not suggest how to use it. I am using afterFind() in model like this:




protected function afterFind() {

parent::afterFind();

$this->create_time = Yii::app()->dateFormatter->formatDateTime(

        CDateTimeParser::parse(

            $this->create_time, 'yyyy-MM-dd hh:mm:ss'

        ), 'short', 'short'

    );

return true;

}



Can anyone suggest why the create_time is being zero filled when using afterFind()?

afterFind is a void method and shouldn’t return anything.

Also, try something simpler to narrow down where the error is taking place.




// Not tested

public function afterFind()

{

    $this->create_time = date('F, j, Y', strtotime($this->create_time));


    parent::afterFind();

}



I do something similar to convert UTC time to my user’s local time. I’ve implemented it as a behavior but you could do the same in the model.




// Model


    public function behaviors()

    {

        return array(

            'CTimestampBehavior' => array(

                'class' => 'zii.behaviors.CTimestampBehavior',

                'createAttribute' => 'created',

                'updateAttribute' => null,

            ),

            'TimezoneBehavior' => array(

                'class' => 'application.components.behaviors.BNDTimezoneBehavior',

                'attributes' => array(

                    'created'

                )

            ),

        );

    }







<?php

/**

 * BNDTimezoneBehavior class file.

 *

 * @author Matt Skelton

 * @date 25-Aug-2012

 */


/**

 * Coverts database datetime fields (stored as UTC) to the user's local timezone.

 */

class BNDTimezoneBehavior extends CActiveRecordBehavior

{

    public $attributes = array();


    /**

     * Converts the database's stored DateTime field into the user's local time.

     * @param CEvent $event

     */

    public function afterFind($event)

    {

        if (Yii::app() instanceof CWebApplication)

        {

            if (Yii::app()->user->getState('timezone'))

            {

                $timezone = Yii::app()->user->timezone;


                foreach ($this->attributes as $attribute)

                {

                    $date = $this->getOwner()->{$attribute};

                    $serverTimezone = new DateTimeZone("UTC");

                    $localTimezone = $timezone;


                    $date = new DateTime($date, $serverTimezone);

                    $date->setTimezone(new DateTimeZone($localTimezone));


                    $this->getOwner()->{$attribute} = $date->format('Y-m-d H:i:s');

                }

            }

        }

    }


    /**

     * Converts the user's local time back into UTC.

     * @param CEvent $event

     */

    public function beforeSave($event)

    {

        if (Yii::app() instanceof CWebApplication)

        {

            if (!$this->owner->isNewRecord)

            {

                if (Yii::app()->user->getState('timezone'))

                {

                    $timezone = Yii::app()->user->timezone;


                    foreach ($this->attributes as $attribute)

                    {

                        $date = $this->getOwner()->{$attribute};

                        $serverTimezone = new DateTimeZone("UTC");


                        $date = new DateTime($date, new DateTimeZone($timezone));

                        $date->setTimezone($serverTimezone);


                        $this->getOwner()->{$attribute} = $date->format('Y-m-d H:i:s');

                    }

                }

            }

        }

    }

}

?>

Matt

Hi Matt, the code you provided in the first block did not work either!

What data type is the create_time field using in the DB?

Its datetime.

Hmmm…

Please run this code and see what comes back.




public function afterFind()

{    

    echo date("Y-m-d H:i:s", strtotime($this->create_time));    

    parent::afterFind();

}




If "0000-00-0…", please post your entire model.

Thanks,

Matt

Did this ever get resolved? I think I’m seeing the same issue.

No I am still figuring out the resolution.

Here is another code that I am using now. But it also does not work:


public function beforeSave() {

	if ($this->isNewRecord)

	    $this->cdate = new CDbExpression('NOW()');


	$this->mdate = new CDbExpression('NOW()');


	return parent::beforeSave();

    }


    protected function afterFind() {


	$this->cdate = Yii::app()->dateFormatter->formatDateTime(

			CDateTimeParser::parse(

				$this->cdate, 'yyyy-MM-dd hh:mm:ss'

			), 'short', 'short'


		);


	$this->mdate = Yii::app()->dateFormatter->formatDateTime(

			CDateTimeParser::parse(

				$this->mdate, 'yyyy-MM-dd hh:mm:ss'

			), 'short', 'short'


		);


	return parent::afterFind();

    }



did you try using public instaead of protected

also remove return form "return parent::afterFind();"

i think there is no need of retrun in anywhere on afterfind

You should return true from before* in order for the method to be executed.

I have similar issue, and here is my code, and it’s working in my program. For your reference.




class User extends CActiveRecord

{

...

	public function afterFind()

	{		

		parent::afterFind();

		

		$dateFields=array('user_start_date','user_end_date');

		foreach($dateFields AS $dateField)

		{			

			$dateValue = $this->attributes[$dateField];			

			if($dateValue == '12/31/1969' || $dateValue == '1969-12-31' || $dateValue == '00/00/0000' || $dateValue == '0000-00-00')

			{

				$this->setAttribute($dateField, NULL);

			}

		}			

		return true;

	}

...