Форматирование дат в ActiveForm и в БД

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
rosolovsky
Сообщения: 119
Зарегистрирован: 2014.06.23, 11:44
Откуда: Украина

Форматирование дат в ActiveForm и в БД

Сообщение rosolovsky »

Здравствуйте. Намучался с этими датами, прошу помощи.
В таблице есть 2 поля created и updated с типом DATETIME (выбрал не Unix TimeStamp так как надо будет делать выборки за период)
При заполнении данных в форме эти два поля чисто для информации и они только для чтения.

Код: Выделить всё

<?= $form->field($model, 'created')->textInput([
   'maxlength' => true,
   'readonly'=> true,
   'value' => Yii::$app->formatter->asDatetime($model->created, 'php:d.m.Y H:i:s'),
   ])
?>

<?= $form->field($model, 'updated')->textInput([
   'maxlength' => true,
   'readonly'=> true,
   'value' => Yii::$app->formatter->asDatetime($model->updated, 'php:d.m.Y H:i:s'),
   ])
?>
далее при сохраненнии в модели есть стандартный бихейвор

Код: Выделить всё

public function behaviors()
    {
        return [
            [
                'class' => 'yii\behaviors\TimestampBehavior',
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_INSERT => ['created', 'updated'],
                    ActiveRecord::EVENT_BEFORE_UPDATE => ['updated'],
                ],
                'value' => function () { 
                    $date = new Expression('NOW()');
                    return $date;
                }
            ],
        ];
    }
При добавлении новой записи в таблицу пишутся правильные даты и время, в таком виде "2018-03-18 21:29:11", бихейвер отрабатывает.
Ну а в форме пользователю отображается тоже то что надо благодаря форматированию
в actionCreate

Код: Выделить всё

$date = new DateTime();
$model->created = Yii::$app->formatter->asDatetime($date,'php:d.m.Y H:i:s');
$model->updated = Yii::$app->formatter->asDatetime($date,'php:d.m.Y H:i:s');
Тут вроде понятно.

Но вот при апдейте формы в экшене actionUpdate смотрю в логах такой вот запрос

Код: Выделить всё

UPDATE `products` SET `created`='18.03.2018 20:33:38', `updated`=NOW(), `code`='111', `is_active`=1 WHERE `id`='1'
Поле created при update запросе вообще не должно было затрагиваться, но так как в форме есть это поле со значением то оно затрагивается и естественно в таблицу в поле created не попадает ничего, потому что в запросе не тот формат даты и времени который нужен БД и в результате в created получается "0000-00-00 00:00:00". Ну тут понятно формат не тот, потому и нули в таблице.
Но после апдейта в поле updated попадает правильная дата в правильном формате но в форме в инпуте уже отображается "NOW()" если поле не форматировать, а если форматировать вот так

Код: Выделить всё

Yii::$app->formatter->asDatetime($model->updated, 'php:d.m.Y H:i:s'),
то в логах ошибка

Код: Выделить всё

Exception: DateTime::__construct(): Failed to parse time string (NOW()) at position 3 ((): Unexpected character in 
Ну логично что форматтер не может это распарсить так как это строка "NOW()"
Почему после апдейта в таблицу попадает нужная дата, а в инпут формы тупо строка "NOW()" или ошибка? Может у меня подход к этому делу неправильный?
Если кто сможет помочь, тому большое спасибо :)
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Форматирование дат в ActiveForm и в БД

Сообщение andku83 »

ну во-первых не нужно создавать инпутов для этих полей - просто выводите их отформатированное значение в html.
во-вторых если уж хочется их запихнуть в инпут, то у этого инпута установите атрибут disabled
rosolovsky
Сообщения: 119
Зарегистрирован: 2014.06.23, 11:44
Откуда: Украина

Re: Форматирование дат в ActiveForm и в БД

Сообщение rosolovsky »

Ну так и есть, инпуты readonly

Код: Выделить всё

<?= $form->field($model, 'created')->textInput([
   'maxlength' => true,
   'readonly'=> true,
   'value' => Yii::$app->formatter->asDatetime($model->created, 'php:d.m.Y H:i:s'),
   ])
?>
Ну просто инпуты органично в форме сидят :)
Но даже если выводить каким либо html то все равно я получаю строку "NOW()"
rosolovsky
Сообщения: 119
Зарегистрирован: 2014.06.23, 11:44
Откуда: Украина

Re: Форматирование дат в ActiveForm и в БД

Сообщение rosolovsky »

А кстати да, если поменять

Код: Выделить всё

'readonly'=> true
на

Код: Выделить всё

'disabled'=> true
То поле в апдейте не участвует, хотя и есть на форме.
Но что делать с этим "NOW()" который попадает в инпут тупо как строка?
Видать

Код: Выделить всё

 $date = new Expression('NOW()');
в БД отрабатывает как надо, а в форме получается фигня.
rosolovsky
Сообщения: 119
Зарегистрирован: 2014.06.23, 11:44
Откуда: Украина

Re: Форматирование дат в ActiveForm и в БД

Сообщение rosolovsky »

Хм, вот так всегда, как только задам вопрос на форуме, немного позднее нахожу ответ
Оказывается если в actionUpdate добавить

Код: Выделить всё

$model->refresh();
то все проблемы уходят :)
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Форматирование дат в ActiveForm и в БД

Сообщение andku83 »

rosolovsky писал(а): 2018.03.18, 23:08 В таблице есть 2 поля created и updated с типом DATETIME (выбрал не Unix TimeStamp так как надо будет делать выборки за период)
это не повод не использовать таймстамп, по нему тоже можно делать выборки запериод


говорите что они только для чтения, но зачем-то записываете туда значение:
rosolovsky писал(а): 2018.03.18, 23:08Ну а в форме пользователю отображается тоже то что надо благодаря форматированию
в actionCreate

Код: Выделить всё

$date = new DateTime();
$model->created = Yii::$app->formatter->asDatetime($date,'php:d.m.Y H:i:s');
$model->updated = Yii::$app->formatter->asDatetime($date,'php:d.m.Y H:i:s');
уберите эту каку из контроллера, все равно если вы сделаете disabled то то что видит пользователь в инпуте будет неактуально
Ответить