#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 .