- Tip 1: Use a prebuilt extension
- Tip 2: Use TimeStamp Behavior for auto-saving date/time records
- Tip 3: Controlling global formats
- Tip 4: Easily convert any attribute format before saving to db
You would find having such a need in most Yii Projects. Your database needs a specific format to store date fields, while you may want to display it in different formats to the users on forms and other views.
How do you manage this situation easily of controlling global formats for date to save and display across your Yii application?
Here are a few pointers:
Tip 1: Use a prebuilt extension ¶
The yii2-datecontrol extension allows you to setup global formats for DATE FIELDS separately for save and view on the form. You can use this for most of the FORM based interfaces, as it allows you to use INPUTS and WIDGETS.
Tip 2: Use TimeStamp Behavior for auto-saving date/time records ¶
For cases, where you want to auto-save the date time field like created_on
and updated_on
, you can use the \yii\behaviors\TimeStampBehavior. You can configure the behavior to automatically save timestamp fields on INSERT AND UPDATE events by default - or you can add additional events.
Some additional tips when using this behavior:
Tip 2.1: Format for saving ¶
You can choose to save a specific timestamp value using a predefined format. So let's take you have defined your datetime field in the backend as an INTEGER and you want to save it as a integer. You can set the behavior like this:
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time',
ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
],
'value' => function() { return date('U'); // unix timestamp },
],
];
}
Tip 2.2: Save Timestamp other than INSERT or UPDATE ¶
You may want to save the timestamp for custom scenarios. Let's say you want to update creation_time for a specific controller action. In that situation you can trigger the timestamp update for your specific attribute by the following:
$model->timestamp->touch('creation_time');
Tip 3: Controlling global formats ¶
You can configure yii\i18n\formatter to control your global date formats for display for your locale. You can set something like this in your config file that you can access across
'formatter' => [
'class' => 'yii\i18n\Formatter',
'dateFormat' => 'php:d-M-Y',
'datetimeFormat' => 'php:d-M-Y H:i:s',
'timeFormat' => 'php:H:i:s',
]
Then you can display your date times anywhere using the formatter specified formats:
echo \Yii::t('app', 'Today is {0, date}', $yourTimeStampAttr);
Tip 4: Easily convert any attribute format before saving to db ¶
In case you do not wish to use the extension as mentioned in Tip # 1, you can create your own global formats for save. Just create a helper class like this:
class Setup {
const DATE_FORMAT = 'php:Y-m-d';
const DATETIME_FORMAT = 'php:Y-m-d H:i:s';
const TIME_FORMAT = 'php:H:i:s';
public static function convert($dateStr, $type='date', $format = null) {
if ($type === 'datetime') {
$fmt = ($format == null) ? self::DATETIME_FORMAT : $format;
}
elseif ($type === 'time') {
$fmt = ($format == null) ? self::TIME_FORMAT : $format;
}
else {
$fmt = ($format == null) ? self::DATE_FORMAT : $format;
}
return \Yii::$app->formatter->asDate($dateStr, $fmt);
}
}
Then anywhere else (like controller/model) you can access this function to convert any input date/time string for saving to database.
$model->dateAttr = Setup::convert($model->dateAttr);
$model->datetimeAttr = Setup::convert($model->datetimeAttr, 'datetime');
Convert all date times
How manipulates dates before 1070 and after 2037 ?
Please check this
http://www.yiiframework.com/forum/index.php/topic/52602-best-way-for-dates-manipulation/page__p__243044__fromsearch__1#entry243044
And this one related wiki
http://www.yiiframework.com/wiki/564/i18n-all-in-one-format-and-timezone-conversions-for-date-time-timestamp-and-datetime
RE: 17252
Anyone please ?
Date fomats
KonApaz... did not get your complete question? If you are asking how to handle such formats after 2038 and before 1970, then
strtotime
for conversion to unix timestamp. It uses something likedate("U", time())
which will work for all dates. So you can convert dates for view and saving using the formatter without much issues.RE: 17276
So, the answer is the Yii2 formatter not use strtotime for convertion.
excellent! I am waiting for Yii2 for production version! (and for many other reasons)
Timezone convertions
Hi
I have not started with Yii.2, so please excuse my questions.
I understand the 'format' conversions, but how do you do 'timezone' conversions for users with different locales? You want to store your times and dates in UTC, so you need to be able to convert it to UTC and back to the user's timezone.
Countries sometimes change their rules pertaining to their daylight-saving-times and their timezones. This means that, in the same country, GMT+05 could be a different time this August compared to last August. How do you keep track of all these countries' changes when doing 'timezone' conversions?
In Yii.1 I use php's DateTime class to do both the 'format' and 'timezone' conversions: i18n all-in-one, with php using the IANA/Olson timezone database to keep track of all the historical and current changes in countries' timezone rules.
Also, for various Yii validation rules, Jquery widgets and mathematical manipulation of dates and times, you need to be able to convert the data into various formats. With php's DateTime class you have full control over these conversions.
The DateTime class was introduced in php 5.2.
But I would like to know if Yii.2 tackles this differently.
Many thanx
Re: Timezone convertions
@Gerhard - Yii 2 uses PHP intl extension and is expected to use the extension's Internationalization features for formatting dates, numbers and even do translations using
Yii::t
.In my extension yii2-datecontrol I strive to use PHP DateTime format without need for php intl extension (as that may not be available on a consistent version across various webhosts). I plan to include timezone support a bit later in this.
Error - Setting read only property
I put this in my config file.
'formatter' => [ 'class' => 'yii\i18n\Formatter', 'dateFormat' => 'd-M-Y', 'datetimeFormat' => 'd-M-Y H:i:s', 'timeFormat' => 'H:i:s', ]
But I'm getting the following error
Re: Timezone conversions
@Gerhard timezone conversion is now supported in yii2-datecontrol extension.
Re: Formatter error
@Sreenadh - check the docs for yii\i18n\Formatter.
This class has been drastically upgraded since this wiki was written. It supports ICU format by default. For PHP datetime formats you need to prepend the string
php:
to your format strings.The wiki has been changed to reflect PHP formats - but it may need some edits for the new Formatter class.
Timezone conversions
Okay thanx. Will check it out.
Where should I put this code?
public function behaviors() { return [ 'timestamp' => [ 'class' => TimestampBehavior::className(), 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time', ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time', ], 'value' => function() { return date('U'); // unix timestamp }, ], ]; }
Code Error on Public Behaviors function
@Muhammad Shahzad
In this case, public function behaviors() goes in your model class. For more information, check this page out.
Using Time Stamp Behaviour
Also, the code mentioned will give you an error because the comment is omitting the closing curly brackets. The code below should work correctly.
public function behaviors() { return [ 'timestamp' => [ 'class' => TimestampBehavior::className(), 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time', ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time', ], 'value' => function() { return date('U'); // unix timestamp }, ], ]; }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.