How to deal with unixtime from Active Record in views

Hi all,

I decided to store only unixtime (from 1.1.1970, epoch) in my database, the benefit is an easy conversion to different timezones, simple calculations and no problems with the 1-hour shift due to day-light-saving two times a year. So the CActiveModel classes have only unixtime in their properties.

Now I want to make some views to change data on the model, also the date/time properties. As recommended the controller simply do a massive-assignment, so don’t deal with the properties and their content. The views basically only fill a form with the data requested by the model.

But the problem is, that I don’t want to show the unixtime to the user, they should see a locale dependent formatted date like “dd.mm.yyyy” and also enter this format. Even a simple form of offering a text-input line where the user sees and enter a date/time string is not so easy to be converted in unixtime due to the MVC architecture…

(Best would be to use the CJuiDatePicker but this seems to have a bug not being compatible in unixtime format (see here) and it also still shows the ugly unixtime number)

How to convert unixtime from inside model to locale format in view within the Yii way of MVC/ActiveRecord/MassiveAssignment…

Thanks a lot

Achim

In your model do the following:




public function afterFind()

{

      $this->date = date('date format' , $this->date);    

       // native php date method so sub the first param with your locale string  

      return parent::afterFind(); 

} 



Be sure to call the parent method too…

Thanks a lot for your help!!

To be locale dependend I prefer the CDateFormatter over date().

Furthermore I’ve added the other direction of saving modified data back to the model by using beforeValidate() in the same way, so I got good results with this in the model class:




public function afterFind()

{

      $this->date = Yii::app()->dateFormatter->formatDateTime($this->date, 'medium','short');

      return parent::afterFind(); 

}


public function beforeValidate()

{

	$this->date = CDateTimeParser::parse(

		$this->date,

		Yii::app()->locale->getDateFormat('medium').' '.Yii::app()->locale->getTimeFormat('short')

	);

	return parent::beforeValidate();

}




So basically it works, but…

It now overwrites (hides) the unixtime in the model completly, I have no chance to access the unixtime from Yii at all. But I need to :frowning:

There are some other classes making calculations with the date/time, this is also one of the reasons why I’ve choosen unixtime in the model. With this implementation also other models can’t access the unixtime anymore.

I would prefer a solution where the conversion between unixtime and locale depended date/time is done in the view or controller. Also from the MVC pattern theory it should belong to the view rather than the model… I guess.

But maybe these are the limitations of Yii ActiveData realization with massive assignment.

It just came into my mind that I could also replace the massive assignment in the controller by simply do a "manual" assignment for each property. In this I could do the both conversions as mentioned above both ways between unixtime and locale time within the controller - a lot of afford, because I have to hard-code each property within the controller…hmm

Update:

I just realized that the conversion unixtime and locale depended time have to go out of the model, because I have views which display the same date in different formats. Sometimes it is only "short" format, sometimes it is "full" so with day-of-week and also with seconds at the time. The same unixtime field should be formatted differently… from my gut-feeling this should go into view-class.

Cheers

Achim

I did something similar but I used a public model variable for holding the converted datetime as well as passing it to and from the view.

/Tommy

Maybe you also need :




protected function beforeSave(){ 

    // your code here 

    return parent::beforeSave(); 

} 



…to make the date go back to a timestamp.

…it looks like beforeValidate() is called before beforeSave() as well. At least, I tested it, it works…

But as discussed before, I don’t recommend touching the model for this kind of conversion, it shall be handled at view or controller. this gives much more flexibility and keeps the model clean at business logic.