Predvoditelev.RU
Заметки

Yii2: Вывод и сохранение даты в различных форматах

Часто встречающаяся задача: отображать дату в форме в одном формате, а сохранять в базе данных в другом.

Существуют несколько способов решения:

  • Использовать виджет Date Control от Kartik'a.
  • Сделать отдельное поле в модели с геттером и сеттером, которые будут выполнять необходимые преобразования.
  • С помощью методов afterFind и beforeSave выполнять преобразования перед сохранением и после получения модели из базы данных соответственно.
  • Прочие велосипеды :)

Собственно, ещё один велосипед.

Валидатор для преобразования даты

Создаём класс валидатора, который на лету преобразовывает дату в нужный формат:

class AsDateValidator extends Validator
{
    public $format = 'yyyy-MM-dd';

    public function validateAttribute($model, $attribute)
    {
        switch ($this->format) {
            case 'U':
            case 'timestamp':
                $value = Yii::$app->formatter->asTimestamp($model->$attribute);
                break;
            default:
            $value = Yii::$app->formatter->asDate($model->$attribute, $this->format);
        }
        $model->$attribute = $value;
    }
}

Формат даты задаётся с помощью параметра format. В качестве формата поддерживаются любые значения, принимаемые функцией Yii::$app->formatter->asDate, а также U или timestamp.

Примеры использования правила валидации в модели:

['birthday', AsDateValidator::className(), 'format' => 'php:Y-m-d'], // 2017-07-26
['date', AsDateValidator::className(), 'format' => 'dd.MM.yyyy HH:mm:ss'], // 15.07.2017 02:15:20
['dayX', AsDateValidator::className(), 'format' => 'U'], // 1501020241
['dayZ', AsDateValidator::className(), 'format' => 'timestamp'], // 1501020241