Преобразование даты MySQL в PHP DateTime в Symfony2.8-Form

У меня есть объект Symfony, сохраняющий день рождения следующим образом:

/**
 * @var \DateTime
 * @Gedmo\Versioned
 * @ORM\Column(name="birthday", type="date", nullable=true)
 */
protected $birthday;

Соответственно в MySQL день рождения хранится как дата. Теперь, чтобы отредактировать сущность, я использую форму с полем Symfony DateType для дня рождения:

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
        ...
        ->add('birthday', DateType::class, [
                'required' => false,
                'widget' => 'single_text',
                'format' => 'dd.MM.yyyy',
                'attr'=> [
                        'style'=>'',
                ],
        ])
        ...
    ;
}

Интересно, что когда день рождения, хранящийся в базе данных, является датой до пятницы, 13 декабря 1901 года, в форме отображается неправильная дата (фактически дата за день до этого). Чтобы узнать, что происходит, я изменил атрибут формата в построителе форм на:

                'format' => 'dd.MM.yyyy HH:mm:ss z',

и, например, если дата «26.02.1825», в поле формы отображается «25.02.1825 23:53:28 GMT+0:53:28», что выглядит так, как будто используется очень странный часовой пояс. Итак, я думаю, должна быть проблема, когда запись даты MySQL преобразуется в объект DateTime в PHP с помощью Doctrine?

В качестве обходного пути я добавил 60 минут к преобразованному значению (в получателе свойства), но должен быть правильный способ справиться с этим. Может ли кто-нибудь помочь мне здесь?

Я уверен, что это было проблемой раньше, но я действительно не мог найти похожих вопросов...

Версии:

  • PHP 7.0.27
  • Симфония 2.8
  • Доктрина 1.6

person Calcux    schedule 16.02.2018    source источник


Ответы (1)


Я нашел способ вызвать ошибку на более низком уровне кода:

$timestamp = -4570909200;
$dateTime = new \DateTime();
$dateTime->setTimestamp($timestamp);
print($dateTime->format('d.m.Y H:i:s').'<br>');
$formatter = new \IntlDateFormatter(\Locale::getDefault(), \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE, 'Europe/Berlin', \IntlDateFormatter::GREGORIAN, 'dd.MM.yyyy HH:mm:ss (z)');
$formatter->setLenient(false);
$formatted = $formatter->format($timestamp);
print($formatted);

Это дает следующий результат:

26.02.1825 00:00:00
25.02.1825 23:53:28 (GMT+0:53:28)

Часовые пояса, такие как «Европа/Лондон» или «Европа/Цюрих», дают разные, но такие же странные результаты. Может быть, не следует использовать эти специальные часовые пояса, а лучше «CET»?

Я, наконец, также нашел аналогичный пост, дающий ответ:

неверное преобразование даты/времени PHP IntlDateFormatter

person Calcux    schedule 18.02.2018