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