Должно быть, это одна из самых часто возникающих, и в тоже время, очень простая задача для реализации в 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');