- Introduction
- Set the Locale
- Set the validation rule
- Saving dates
- Formatting dates
- Changing the target language
Introduction ¶
I needed British (dd/mm/yyyy) formatted dates throughout my application but found it very difficult to find examples of how to do this - until I found this excellent forum post http://www.yiiframework.com/forum/index.php?/topic/3649-dealing-with-i18n-date-formats/
So here is my complete solution - note that I'm using the 'short' date format throughout.
Set the Locale ¶
Add this line to protected/main/config.php, I have it just after the application name
return array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'name'=>'My Application',
'sourceLanguage'=>'en_gb',
Set the validation rule ¶
In your model, eg: protected/models/client.php add this format rule for any dates
public function rules()
{
return array(
...
array('date_of_birth','date','format'=>Yii::app()->locale->getDateFormat('short')),
...
Saving dates ¶
I've modified the above forum post so that its set for short dates. Again this is in your model
protected function beforeSave()
{
if(parent::beforeSave())
{
// Format dates based on the locale
foreach($this->metadata->tableSchema->columns as $columnName => $column)
{
if ($column->dbType == 'date')
{
$this->$columnName = date('Y-m-d',
CDateTimeParser::parse($this->$columnName,
Yii::app()->locale->getDateFormat('short')));
}
elseif ($column->dbType == 'datetime')
{
$this->$columnName = date('Y-m-d H:i:s',
CDateTimeParser::parse($this->$columnName,
Yii::app()->locale->getDateTimeFormat('short')));
}
}
return true;
}
else
return false;
}
Formatting dates ¶
And finally formatting the dates after a find - again this is in your model.
protected function afterFind()
{
// Format dates based on the locale
foreach($this->metadata->tableSchema->columns as $columnName => $column)
{
if (!strlen($this->$columnName)) continue;
if ($column->dbType == 'date')
{
$this->$columnName = Yii::app()->dateFormatter->formatDateTime(
CDateTimeParser::parse(
$this->$columnName,
'yyyy-MM-dd'
),
'short',null
);
}
elseif ($column->dbType == 'datetime' || $column->dbType == 'timestamp')
{
$this->$columnName = Yii::app()->dateFormatter->formatDateTime(
CDateTimeParser::parse(
$this->$columnName,
'yyyy-MM-dd hh:mm:ss'
),
'short','short'
);
}
}
return parent::afterFind();
}
Changing the target language ¶
In theory (I haven't tested it) you should be able to change the target language on the fly - my plan is when a user registers, the locale is set after login and so the dates are formatted accordingly.
Yii::app()->setLanguage($lang);
Or simply use i18n-datetime-behavior
URL: http://www.yiiframework.com/extension/i18n-datetime-behavior/
Set the Locale
I only had the issue with this part
return array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'My Application', 'sourceLanguage'=>'en_gb',
It worked like a willy .. when I changes in my config (main.php)
'sourceLanguage'=>'en_gb',
to
'Language'=>'en_gb',
thats it,
Thanks and Kodoes for the rest of the code
problem with datetime columns
there is a bug:
Yii::app()->locale->getDateTimeFormat('short')));
returns "{1} {0}" and cannot be directly used for date parse.
Instead I use:
strtr(Yii::app()->locale->getDateTimeFormat(), array("{0}" => Yii::app()->locale->getTimeFormat('short'), "{1}" => Yii::app()->locale->getDateFormat('short')));
Timestamp
Hi
How do you do this with dates that fall outside the Unix timestamp?
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.