Yii2: Сохранение и отображение даты/времени

Должно быть, это одна из самых часто возникающих, и в тоже время, очень простая задача для реализации в Yii 2.0.

Зачастую мы сохраняем дату/время в базе данных в одном формате, а вывести на экран ее нужно в другом формате.

Многие уходят огородами и изобретают свои велосипеды. Ниже представлены несколько простых советов, которые помогут в освоении работы с данными в формате дата/время в фреймворке Yii2.

1. Все уже придумано до нас

Можно использовать готовое расширение yii2-datecontrol, которое позволяет глобально определить разные форматы для сохранения и отображения в представлении. Данное расширение можно использовать в большинстве случаев форм, оно доступно как в инпутах, так и виджетах.

2. Использовать поведение TimeStamp для автоматического сохранения данных в базу

Например, если нужно автоматически сохранять дату/время создания/обновления записи, можно использовать представление \yii\behaviors\TimeStampBehavior. Это поведение можно настроить на работу со стандартными событиями INSERT и UPDATE или создать свои события.

2.1. Формат сохранения даты/времени

Для сохранения timestamp в нужном формате в поле типа  integer поведение нужно настроить примерно так:

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 },
        ],
    ];
}
<h2>2.2. Сохраняем timestamp по другому событию</h2>

Если возникла необходимость сохранить <strong>timestamp</strong> при другом сценарии, например нужно обновить значение поля <strong>creation_time</strong> в определенном действии какого-нибудь контроллера. В данном случае поведение можно вызвать так:
$model->timestamp->touch('creation_time');

3. Устанавливаем глобальные форматы

Можно настроить yii\i18n\formatter для определения глобальных форматов отображения даты/времени для нужной локали. Пример:

'formatter' => [
    'class' => 'yii\i18n\Formatter',
    'dateFormat' => 'php:d.m.Y',
    'datetimeFormat' => 'php:d.m.Y H:i:s',
    'timeFormat' => 'php:H:i:s',
]

В дальнейшем отображение даты сведется к простому:

echo \Yii::t('app', 'Today is {0, date}', $yourTimeStampAttr);
<h1>4. Простая конвертация данных перед сохранением в базу</h1>

Если вы не хотите использовать расширение из первого совета,  можете создать свои форматы для сохранения. Например, используя <strong>helper</strong> класс:
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);
    }
}

Теперь в любом контроллере или модели можно использовать описанные выше функции для преобразования даты/времени из строки в нужный формат:

$model->dateAttr = Setup::convert($model->dateAttr);
$model->datetimeAttr = Setup::convert($model->datetimeAttr, 'datetime');

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *