Разные типы часовых поясов для объекта DateTime

#php #json #datetime

#php #postgresql #datetime #Часовой пояс

Вопрос:

Я использую Doctrine2 в Postgres. В одной таблице у меня есть два разных типа дат: birthdate:date и created_at:datetimetz . Оба становятся объектом DateTime, но с разными timezone_type . Вот списки:

created_at datetimetz:

 DateTime Object
(
    [date] => 2013-04-18 11:54:34
    [timezone_type] => 1
    [timezone] =>  02:00
)
  

birthdate Дата:

 DateTime Object
(
    [date] => 1970-01-01 00:00:00
    [timezone_type] => 3
    [timezone] => Europe/Berlin
)
  

Мне нужно отформатировать мои объекты таким же образом. Оба должны иметь timezone_type=3 .

Как я могу этого добиться?

Комментарии:

1. date_timezone_set ( DateTime $object , DateTimeZone $timezone )

2. Предлагаемый вами код устанавливает только часовой пояс. В приведенных выше списках часовые пояса одинаковы, но они представлены по-разному.

3. Если вы используете $mytime->setTimezone(new DateTimezone('Europe/Berlin')) (или что-то еще) для каждого из них, результатом будет то, что они представлены одинаково.

Ответ №1:

Часовые пояса могут быть одного из трех разных типов в объектах DateTime:

  • Введите 1; Смещение UTC, например, в new DateTime("17 July 2013 -0300");
  • Введите 2; Сокращение часового пояса, например, в new DateTime("17 July 2013 GMT");
  • Тип 3: идентификатор часового пояса, например, в new DateTime( "17 July 2013", new DateTimeZone("Europe/London"));

Только объекты DateTime с привязанными часовыми поясами типа 3 позволят корректно использовать летнее время.

Чтобы всегда иметь тип 3, вам нужно будет сохранить часовой пояс в вашей базе данных в качестве принятых идентификаторов из этого списка и применить его к вашему объекту DateTime при создании экземпляра.

Комментарии:

1. Хорошо.. Я сохраняю часовой пояс этого типа 3 в базе данных. Проблема заключается в том, что Doctrine2 возвращает эти разные типы часовых поясов (даже после того, как я явно передаю часовой пояс как DateTimeZone(«Европа / Лондон»)). Я не думаю, что у меня есть легкий доступ к изменению поведения Doctrine2, поэтому я уже решил использовать простые временные метки с классом consumer для форматирования даты и времени. Или, может быть, я оставил что-то незамеченным? Вы когда-нибудь работали с объектами DateTime из Doctrine2 Postgres и заставляли их работать?

2. Столкнувшись с той же проблемой с другим ORM, я обнаружил, что $new=new DateTime(); $new->setTimestamp($old->getTimestamp()); это помогает, хотя и очень некрасиво. Включение этого в установщики облегчает проблему.

3. @Softlion если я добавлю 6 месяцев к DateTime в типе 1, это будет 1 час, так как он не будет знать о переходе на летнее время, который произойдет примерно в октябре. Тип 3 будет правильно учитывать переход.

4. @vascowhite Это отображение указано где-нибудь в документации?

5. @GPHemsley Я так не думаю. Я обнаружил это, протестировав и прочитав исходный код. Я смутно помню, что где-то читал комментарий, который подтвердил мои выводы, но это было давно, и я не могу вспомнить, где.

Ответ №2:

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

@vascowhite верен, но в отношении Doctrine (по крайней мере, в моей конфигурации) даты, отправляемые на сервер (например, для сохранения) через HTTP, преобразуются в тип часового пояса 2. Doctrine обрабатывает их правильно и правильно сохраняет дату, но не преобразует тип часового пояса.

Если вы выполняете операцию типа «сохранить и и вернуть новые значения», обратите внимание, что Doctrine будет использовать кэшированное значение (с timezone_type 2 ). Это становится важным, когда вы ожидаете timezone_type 3, как вы обычно получаете во время перезагрузки страницы. У нас есть пользовательский класс JS-преобразователя даты, который ожидает timezone_type 3, и он не смог его преобразовать. По общему признанию, конвертер дат должен учитывать это, но также следует знать, что тип часового пояса будет последним загруженным значением в Doctrine. Очистка кэша Doctrine после сохранения приведет к перезагрузке данных с использованием timezone_type 3 .