Date Control yii2-datecontrol   Tips

Latest Stable Version Latest Unstable Version Total Downloads Monthly Downloads Daily Downloads
Thankful to Krajee!
to get more out of us.

NOTE: This extension depends on the kartik-v/yii2-krajee-base extension which in turn depends on the yiisoft/yii2-bootstrap extension. Check the composer.json for this extension's requirements and dependencies that may be updated by composer.

The Date Control module allows controlling date formats of attributes separately for View and Model for Yii Framework 2.0. It allows you to set a separate format for saving dates to database and a separate format for display to users in your forms. It includes support out of the box for the enhanced DatePicker, DateTimePicker, and TimePicker widgets from yii2-widgets. In addition, you could configure any other date picker widget to be used with this module. With release 1.2.0, this module has various enhancements. It includes a separate DateFormatter library to manipulate dates in javascript using PHP DateTime formats. It does not require Intl extension for formatting nor the PHP 64 bit, and supports all date values (before 1970 and after 2037). It also includes preconfigured translations for most common languages (locales) and works well with kartik\widgets\DatePicker and kartik\widgets\DatePicker. This release tightens and enhances the DateControl integration with kartik\widgets\DatePicker, by allowing keyboard manipulation of dates. However, it is recommended to use the extension with ajaxConversion set to true if you need seamless integration with PHP DateTime functions like timezone support.

Important

  • Version 1.5.0 has BC breaking changes. This release now adds supports for both ICU and PHP date format patterns. By default the format will be parsed as a ICU date pattern. In order to pass a PHP Date format - prepend your format pattern with the string php:.

  • Version 1.9.5 has BC breaking changes. A new property widgetOptions is available. This will replace the options property for the scenario when autoWidget or widgetClass is set.

When working with the great Yii Framework, one of the most common observations I had was the need to have a proper control on the date settings. The date settings for each Yii application, are unique to each application and region. Most Yii developers or users almost always need an option of displaying date and time in ONE specific format, but save them to database in ANOTHER format. So to summarize, the problem statement was:

  • Lack of a single configuration method to display date & times to user (or VIEW) in ONE format
  • Lack of a configuration method to save date & times in database (or MODEL) in ANOTHER format

Most existing Yii solutions try to overcome the above by setting the format in model->afterFind, present in view, then unformat it in model->setAttribues or model->beforeValidate. This was still an issue when had one many models and views in the application and changes in development cycle, had to be replicated in many places (more complex scenarios being multi-regional formats).

This module helps overcome this large gap by addressing all of these at the presentational level. The module enables one to configure the date and time settings separately for DISPLAY and SAVE. This can be setup either globally or individually at each DateControl widget level. And if this is not useful enough, it automatically enables any date/time picker widgets to be used in conjunction with this.

How this magic works, is that the extension just alters this at the presentational layer (VIEW). It automatically sets the base model input to hidden and displays a mirror input in the display format one has set. Then on each edit of the display input, the extension traps the change event, and overrwrites the hidden base model input as per the desired save format. The other good thing is, that the extension automatically triggers the javascript change event for the base model input as well. Thus all client model validations and other jquery events needed by Picker widgets are automatically triggered.

NOTE

All date and time formats used across this module follow one standard - i.e. PHP Date Time format strings. The extension automatically provides three widgets to display and control the date-time inputs.
View a complete demo.

The preferred way to install this extension is through composer. Either run:

$ php composer.phar require kartik-v/yii2-datecontrol "dev-master"

or add:

"kartik-v/yii2-datecontrol": "dev-master"

to the require section of your composer.json file. Then run:

php composer.phar update

to get the updated package on your application install.

Note

With release 1.2.0, this extension now uses the php-date-formatter.js library by Krajee. This lean library helps manipulate dates in javascript easily and quickly using PHP DateTime formats.

Display Format Defaulting Rules

The rules for deriving the display format for each type (date, datetime, or time) is validated in the following sequence:

  1. if displayFormat is set in DateControl widget, it will be first used

  2. else if Yii::$app->params['dateControlDisplay'] is set, it will be next used

  3. else, the format as set in Module::displaySettings will be used from the DateControl Module

  4. else, the format as set in Yii::$app->formatter will be used


Save Format Defaulting Rules

The rules for deriving the save format for each type (date, datetime, or time) is validated in the following sequence:

  1. if saveFormat is set in DateControl widget, it will be first used

  2. else if Yii::$app->params['dateControlSave'] is set, it will be next used

  3. else, the format as set in Module::saveSettings will be used from the DateControl Module

  4. else, the format as set in Yii::$app->formatter will be used


Example setup in Yii::$app->params
use kartik\datecontrol\Module;
// other settings
'params' => [
    // format settings for displaying each date attribute (ICU format example)
    'dateControlDisplay' => [
        Module::FORMAT_DATE => 'dd-MM-yyyy',
        Module::FORMAT_TIME => 'hh:mm:ss a',
        Module::FORMAT_DATETIME => 'dd-MM-yyyy hh:mm:ss a', 
    ],
    
    // format settings for saving each date attribute (PHP format example)
    'dateControlSave' => [
        Module::FORMAT_DATE => 'php:U', // saves as unix timestamp
        Module::FORMAT_TIME => 'php:H:i:s',
        Module::FORMAT_DATETIME => 'php:Y-m-d H:i:s',
    ]
]

The extension has been created as a module to enable access to global settings for your application. In addition, it allows you to read and format date times between client and server using PHP DateTime object. The DateControl widget uses ajax processing to convert display (view) format to model (save) format. The module must be named datecontrol as shown below:
'modules' => [
   'datecontrol' =>  [
        'class' => '\kartik\datecontrol\Module'
    ]
];
The module can take in the following parameters:
  • displaySettings: array, the format settings for displaying each date attribute (in the view). An associative array that need to be setup as $type => $format, where:

    • type: string, one of the following formats:

      • Module::FORMAT_DATE or 'date'.

      • Module::FORMAT_TIME or 'time'.

      • Module::FORMAT_DATETIME or 'datetime'.

    • format: string the PHP date format string

    The Yii::$app->params['dateControlDisplay'] setting will override this. If this is not set, the display settings will automatically be derived from Yii::$app->formatter based on the type setting in the DateControl widget.

  • saveSettings: array, the format settings for saving each date attribute (to the model). An associative array that need to be setup as $type => $format, where:

    • type: string, one of the following formats:

      • Module::FORMAT_DATE or 'date'.

      • Module::FORMAT_TIME or 'time'.

      • Module::FORMAT_DATETIME or 'datetime'.

    • format: string the PHP date format string. Set this to 'php:U' to save it as Unix timestamp.

    The Yii::$app->params['dateControlSave'] setting will override this. If this is not set, the display settings will automatically be derived from Yii::$app->formatter based on the type setting in the DateControl widget.

  • displayTimezone: string,the timezone for the displayed date. Must be one of the PHP DateTimeZone formats. If not set, no timezone setting will be applied for formatting. Note: Timezones will work only if ajaxConversion is set to true.

  • saveTimezone: string,the timezone for the saved date. Must be one of the PHP DateTimeZone formats. If not set, no timezone setting will be applied for formatting. Note: Timezones will work only if ajaxConversion is set to true.

  • autoWidget: boolean, whether to automatically use a preset widget from \kartik\widgets based on $type. The following widgets will be automatically set for the formats:

    • \kartik\widgets\DatePicker for Module::FORMAT_DATE

    • \kartik\widgets\TimePicker for Module::FORMAT_TIME

    • \kartik\widgets\DateTimePicker for Module::FORMAT_DATETIME

    If this is not set, it will default to true.

  • widgetSettings: array, the widget settings that will be used to render the date input. NOTE: If autoWidget is true, this will be auto-generated, as explained above. An associative array that need to be setup as $type => $settings, where:

    • type: string, one of the following formats:

      • Module::FORMAT_DATE or 'date'.

      • Module::FORMAT_TIME or 'time'.

      • Module::FORMAT_DATETIME or 'datetime'.

    • settings: array which consists of these keys:

      • class: string the widget class name for the input widget that will render the date input.

      • options: array the HTML attributes for the input widget

  • convertAction: string, the route/action to convert the date as per the saveFormat in DateControl widget. Defaults to '/datecontrol/parse/convert'

  • ajaxConversion: boolean, whether to use ajax based date conversion from display to save formats. If set to false, the plugin will use php-date-formatter.js to convert to the set formats using client side validation. Defaults to true.

Usage

use \kartik\datecontrol\Module;
// other settings
'modules' => [
   'datecontrol' =>  [
        'class' => 'kartik\datecontrol\Module',

        // format settings for displaying each date attribute (ICU format example)
        'displaySettings' => [
            Module::FORMAT_DATE => 'dd-MM-yyyy',
            Module::FORMAT_TIME => 'hh:mm:ss a',
            Module::FORMAT_DATETIME => 'dd-MM-yyyy hh:mm:ss a', 
        ],
        
        // format settings for saving each date attribute (PHP format example)
        'saveSettings' => [
            Module::FORMAT_DATE => 'php:U', // saves as unix timestamp
            Module::FORMAT_TIME => 'php:H:i:s',
            Module::FORMAT_DATETIME => 'php:Y-m-d H:i:s',
        ],

        // set your display timezone
        'displayTimezone' => 'Asia/Kolkata',

        // set your timezone for date saved to db
        'saveTimezone' => 'UTC',
        
        // automatically use kartik\widgets for each of the above formats
        'autoWidget' => true,

        // default settings for each widget from kartik\widgets used when autoWidget is true
        'autoWidgetSettings' => [
            Module::FORMAT_DATE => ['type'=>2, 'pluginOptions'=>['autoclose'=>true]], // example
            Module::FORMAT_DATETIME => [], // setup if needed
            Module::FORMAT_TIME => [], // setup if needed
        ],
        
        // custom widget settings that will be used to render the date input instead of kartik\widgets,
        // this will be used when autoWidget is set to false at module or widget level.
        'widgetSettings' => [
            Module::FORMAT_DATE => [
                'class' => 'yii\jui\DatePicker', // example
                'options' => [
                    'dateFormat' => 'php:d-M-Y',
                    'options' => ['class'=>'form-control'],
                ]
            ]
        ]
        // other settings
    ]
]

You could set a few configuration options through the Yii::$app->params. This is typically set through your Yii configuration file (e.g. main.php). The settings in params will override whatever you have setup at the module level. The difference in usage of params vs module is that the Yii params gives you an alternative option and also helps override settings at runtime. You can setup the following parameters in Yii::$app->params:

  • dateControlDisplay: array, the format settings for displaying each date attribute (in the view). An associative array that need to be setup as $type => $format, where:

    • type: string, one of the following formats:

      • Module::FORMAT_DATE or 'date'.

      • Module::FORMAT_TIME or 'time'.

      • Module::FORMAT_DATETIME or 'datetime'.

    • format: string the PHP date format string

  • dateControlSave: array, the format settings for saving each date attribute (to the model). An associative array that need to be setup as $type => $format, where:

    • type: string, one of the following formats:

      • Module::FORMAT_DATE or 'date'.

      • Module::FORMAT_TIME or 'time'.

      • Module::FORMAT_DATETIME or 'datetime'.

    • format: string the PHP date format string. Set this to 'php:U' to save it as Unix timestamp.

  • dateControlDisplayTimezone: string,the timezone for the displayed date. Must be one of the PHP DateTimeZone formats. If not set, no timezone setting will be applied for formatting. Note: Timezones will work only if ajaxConversion is set to true.

  • dateControlSaveTimezone: string,the timezone for the saved date. Must be one of the PHP DateTimeZone formats. If not set, no timezone setting will be applied for formatting. Note: Timezones will work only if ajaxConversion is set to true.

The DateControl widget allows you to render a date controlled input in each view. It uses the global settings from the module wherever available. You can override these settings at the widget/view level. The widget allows you to setup the following properties:
  • language: string, the language code used for rendering the dates. This will use the language relatedconfiguration date setting formats, from the configuration in the locales folder of this extension. When autoWidget is true, this will automatically set the languages for DatePicker, DateTimePicker, or TimePicker widgets.

  • type: string, data type to use for the displayed date control. Should be one of the following values:

    • DateControl::FORMAT_DATE or 'date'.

    • DateControl::FORMAT_TIME or 'time'.

    • DateControl::FORMAT_DATETIME or 'datetime'.

  • displayFormat: string,the format string for displaying the date (in the view). If not set, will automatically derive this based on displaySettings in the Module based on the type setting. Note the format can be passed as a ICU format OR a PHP datetime format, exactly as in yii\i18n\Formatter. If you are passing a PHP format, prefix the format with the pattern php:.

  • saveFormat: string, the format string for saving the date (to the model). If not set, will automatically derive this based on saveSettings in the Module based on the type setting. Note the format can be passed as a ICU format OR a PHP datetime format, exactly as in yii\i18n\Formatter. If you are passing a PHP format, prefix the format with the pattern php:.

  • displayTimezone: string,the timezone for the displayed date. Must be one of the PHP DateTimeZone formats. If not set, no timezone setting will be applied for formatting. Note: Timezones will work only if ajaxConversion is set to true.

  • saveTimezone: string,the timezone for the saved date. Must be one of the PHP DateTimeZone formats. If not set, no timezone setting will be applied for formatting. Note: Timezones will work only if ajaxConversion is set to true.

  • autoWidget: boolean, whether to automatically use a preset widget from \kartik\widgets based on $type. This will override the setting at the Module level. The following widgets will be automatically set for the formats:

    • \kartik\widgets\DatePicker for Module::FORMAT_DATE

    • \kartik\widgets\TimePicker for Module::FORMAT_TIME

    • \kartik\widgets\DateTimePicker for Module::FORMAT_DATETIME

  • widgetClass: string, any custom widget class to use. Will only be used if autoWidget is set to false. NOTE: A normal text input will be generated, if this is not set and autoWidget is false

  • widgetOptions: array, the configuration options for the widget which will be parsed only in one of the following cases:

    • when autoWidget is true and this corresponds to widget settings for DatePicker, TimePicker, or DateTimePicker based on the type setting, OR

    • when autoWidget is false and widgetClass is set and this allows to set the configuration options for the particular widget class.

  • options: string, the HTML attributes for the display input. This property is applicable and parsed only if autoWidget is false and widgetClass is NOT set or empty.

  • disabled: boolean whether the input widget is to be entirely disabled. Defaults to false. Note this will disable properly if you use normal HTML inputs OR have autoWidget property set to true. For other custom widgets, this will be applied only if the widget has a disabled property.

  • readonly: boolean whether the input widget is to be entirely readonly. Defaults to false. Note this will set to readonly properly if you use normal HTML inputs OR have autoWidget property set to true. For other custom widgets, this will be applied only if the widget has a readonly property.

  • saveOptions: string, the HTML attributes for the base model input that will be saved typically to database. The following special options are recognized:

    • type: string whether to generate a hidden or text input. Defaults to hidden.

    • label: string any label to be placed before the input. Will be only displayed if type is set to text.

  • ajaxConversion: boolean, whether to use ajax based date conversion from display to save formats. If set to false, the plugin will use php-date-formatter.js to convert to the set formats using client side validation. Defaults to true and is overridden by the value set at Module level.

  • asyncRequest: boolean, whether to fire an asynchronous ajax request (applicable when ajaxConversion is set to true). Defaults to true. You can set this to false for cases, where you need this to be fired synchronously. For example, when using this widget as a filter in \kartik\grid\GridView, with a PJAX enabled grid.

  • pluginOptions: array, the jQuery plugin options for the datecontrol plugin. The following options can be setup:

    • dateSettings: array, This property allows you to configure the terms used for short/long days and months, and the meridiem. This is defaulted to:

      {
          longDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
          shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
          shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
          longMonths: ['January', 'February', 'March', 'April', 'May', 'June',
              'July', 'August', 'September', 'October', 'November', 'December'],
          meridiem: ['AM', 'PM']
      }
      

      This property will be autogenerated from the locales configuration based on the language setting. You can override this at runtime.

For the examples below, the displaySettings and saveSettings are set to the following at the module configuration level :

 // format settings for displaying each date attribute (ICU format example)
'displaySettings' => [
    Module::FORMAT_DATE => 'dd-MM-yyyy',
    Module::FORMAT_TIME => 'hh:mm:ss a',
    Module::FORMAT_DATETIME => 'dd-MM-yyyy hh:mm:ss a', 
],

// format settings for saving each date attribute (PHP format example)
'saveSettings' => [
    Module::FORMAT_DATE => 'php:U', // saves as unix timestamp
    Module::FORMAT_TIME => 'php:H:i:s',
    Module::FORMAT_DATETIME => 'php:Y-m-d H:i:s',
],
View a complete demo.

Input saved as:
Use DatePicker input with ActiveForm and model validation enabled (without ajax conversion). The saved value is displayed for the demo.

Input saved as:
Use a DateTimePicker input with ActiveForm and model validation enabled. The saved value is displayed for the demo.

Input saved as:
Use a TimePicker input with ActiveForm and model validation enabled. The saved value is displayed for the demo.

Input saved as:
Use a plain text input with no model, no ActiveField validation with both custom display and save formats. The saved value is displayed for the demo.

Input saved as:
Use a custom widget, with custom format (ICU notation), and widget options - for example the yii\widgets\MaskedInput.
Input saved as:
Use different timezones. Timezone for display as Pacific/Chatham and for save as UTC.
A disabled DateControl widget setup for time format using kartik\widgets\TimePicker.
use kartik\datecontrol\DateControl;

// Use DatePicker input with ActiveForm and model validation enabled (without ajax conversion). 
echo $form->field($model, 'test_date')->widget(DateControl::classname(), [
    'type'=>DateControl::FORMAT_DATE,
    'ajaxConversion'=>false,
    'widgetOptions' => [
        'pluginOptions' => [
            'autoclose' => true
        ]
    ]
]);

// Use a DateTimePicker input with ActiveForm and model validation enabled. 
echo $form->field($model, 'datetime_1')->widget(DateControl::classname(), [
    'type'=>DateControl::FORMAT_DATETIME
]);

// Use a TimePicker input with ActiveForm and model validation enabled. 
echo $form->field($model, 'datetime_2')->widget(DateControl::classname(), [
    'type'=>DateControl::FORMAT_TIME
]);

// Use a plain text input with no model, no ActiveField validation with both custom display and save formats.
echo DateControl::widget([
    'name'=>'kartik-date', 
    'value'=>time(),
    'type'=>DateControl::FORMAT_TIME,
    'autoWidget'=>false,
    'displayFormat' => 'php:D, d-M-Y H:i:s A'
    'saveFormat' => 'php:U'
]);

//  Use a custom widget, with custom format (ICU notation), and widget options - for example the yii\widgets\MaskedInput.
echo $form->field($model, 'to_date')->widget(DateControl::classname(), [
    'displayFormat' => 'dd/MM/yyyy',
    'autoWidget' => false,
    'widgetClass' => 'yii\widgets\MaskedInput',
    'widgetOptions' => [
        'mask' => '99/99/9999'
    ],
]);

// Use different timezones for display (Pacific/Chatham) and save (UTC)
echo DateControl::widget([
    'name'=>'kartik-date-3', 
    'value'=>time(),
    'type'=>DateControl::FORMAT_DATETIME,
    'displayTimezone'=>'Pacific/Chatham',
    'saveTimezone'=>'UTC'
]);

// A disabled DateControl widget setup for time format using `kartik\widgets\TimePicker`.
echo DateControl::widget([
    'name'=>'kartik-date-3', 
    'value'=>date('H:i:s'),
    'type'=>DateControl::FORMAT_TIME,
    'disabled'=>true
]);

yii2-datecontrol is released under the BSD 3-Clause License. See the bundled LICENSE.md for details.