Yii 2.0: Save and Display Date/Time Fields in different formats in Yii2

34 followers

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');

Total 10 comments

#18357 report it
Gerhard Liebenberg at 2014/10/20 01:34am
Timezone conversions

Okay thanx. Will check it out.

#18341 report it
Kartik V at 2014/10/19 12:00am
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.

#18340 report it
Kartik V at 2014/10/18 11:58pm
Re: Timezone conversions

@Gerhard timezone conversion is now supported in yii2-datecontrol extension.

#18336 report it
Sreenadh at 2014/10/18 06:17am
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

Invalid Callyii\base\InvalidCallException
 
Setting read-only property: yii\web\Application::formatter
#18006 report it
Kartik V at 2014/08/25 09:47pm
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.

#18005 report it
Gerhard Liebenberg at 2014/08/25 05:10pm
Timezone convertions

Hi

I have not started with Yii.2, so please excuse my questions.

  1. 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.

  2. 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

#17277 report it
KonApaz at 2014/05/19 08:39am
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)

#17276 report it
Kartik V at 2014/05/19 08:28am
Date fomats

KonApaz... did not get your complete question? If you are asking how to handle such formats after 2038 and before 1970, then

  • you need to use a type like DATE or DATETIME in MYSQL
  • in Yii2 the formatter has been modified to support dates before 1970 or beyond 2038 by not using strtotime for conversion to unix timestamp. It uses something like date("U", time()) which will work for all dates. So you can convert dates for view and saving using the formatter without much issues.
#17272 report it
KonApaz at 2014/05/19 05:45am
RE: 17252

Anyone please ?

#17252 report it
KonApaz at 2014/05/16 04:21am
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

Leave a comment

Please to leave your comment.

Write new article