I have long been fed up with the way date and time attributes in models have to be handled on a case-by-case basis with no real help from the framework - so I came up with a CBehavior that enables automatic conversion between DATE/DATETIME SQL strings and (UNIX) integer timestamps.
Source code here.
Example of a model that uses the behavior:
/**
* @property int $birthday
*/
class Foo extends CFormModel
{
public $birthday_date = '1975-07-07';
public function behaviors()
{
return array(
'datetime_accessors' => array(
'class' => 'GDateTimeAccessors',
),
);
}
}
Note the @property-annotation, which documents the synchronous accessor for the DATE string attribute.
Here’s an example of how to use this:
$test = new Foo();
echo $test->birthday_date."\n";
echo 'timestamp accessor: '.$test->birthday."\n";
$test->birthday = time();
echo 'new date: '.$test->birthday_date."\n";
echo 'timestamp accessor: '.$test->birthday."\n";
try {
$test->birthday = 'ouch';
} catch (CException $e) {
echo 'expected write-error: '.$e->getMessage()."\n";
}
$test->birthday_date = 'bad bad';
try {
$time = $test->birthday;
} catch (CException $e) {
echo 'expected read-error: '.$e->getMessage()."\n";
}
And the output from running the above example:
1975-07-07
timestamp accessor: 173937600
new date: 2013-01-18
timestamp accessor: 1358485200
expected write-error: property Foo::$birthday accepts only integer or null-values
expected read-error: property Foo::$birthday_date contains an invalid value
By convention, I name my DATE and DATETIME columns in the database with a "_date" or "_datetime" suffix, so that I can manually implement synchronous get/set-accessors for integer timestamp values - this behavior does the same thing, but dynamically for any attributes following the naming conventions.
This is brand new and barely tested, beyond the example shown above, so let me know if this works for you or not.