У меня проблема с получением информации о смещении UTC из PHP DateTimeZone и базовой базы данных. Я подбираюсь близко к каждой паре DT / ST, но часовой пояс с часовым поясом (DT) обычно не такой.
Например (источник):
Восточное Летнее Время (летнее североамериканское восточное время), при наблюдении летнего времени (весна / лето) отстает на 4 часа от всемирного координированного времени (UTC-04: 00).
Восточное стандартное время (стандартное восточное время) при соблюдении стандартного времени (осень / зима) отстает на 5 часов от всемирного координированного времени (UTC-05: 00).
Пока я получаю смещение UTC (в DateTimeZone::getOffset
это сказано против GMT, но я предполагаю, что это то же самое), что и в следующем коде:
$zones = ['EDT', 'EST'];
foreach ($zones as $zone) {
// get offset
$timezone = new DateTimeZone($zone);
$offset = $timezone->getOffset(new DateTime(null, $timezone));
printf("%s (%s) %s\n", $zone, $timezone->getName(), format_offset($offset));
}
Примерный вывод (полный пример, Я использую PHP 5.6.1RC1):
EDT (EDT) -0500
EST (EST) -0500
Эти два часовых пояса на самом деле являются образцовыми, я хотел бы сделать это и с другими, однако я не хочу жестко кодировать смещения, а вместо этого хочу выяснить это с помощью PHP DateTimeZone.
Я мог бы столкнуться с ошибкой здесь, когда я вижу вывод через несколько версий PHP, похоже, что у HHVM нет этой проблемы, если перенести ее:
Output for hhvm-3.2.0 - 3.3.0
EDT (America/New_York) -0400
EST (EST) -0500
Output for 5.5.10 - 5.6.2, php7@20140507 - 20141001
EDT (EDT) -0500
EST (EST) -0500
Output for 5.2.0 - 5.5.9
EDT (America/New_York) -0400
EST (America/New_York) -0400
Существует ли совместимый с PHP-версией способ? Не возиться с DateTimeZone
обычно и до сих пор у меня было впечатление, что это будет хорошо работать.
PHP использует стандарт База данных IANA tz. Вы можете найти список поддерживаемых часовых поясов либо в Википедии, или же в документации PHP.
В частности, вы обнаружите, что такие значения, как "EST"
существуют только для обратной совместимости. Вы можете увидеть это в эта страница из документов, есть большое красное предупреждение о не используя часовые пояса этого формата. И пока "EST"
находится в списке устаревших зон, "EDT"
не является.
В общем, сокращения часовых поясов делают плохие идентификаторы, потому что есть слишком много неясностей. Рассматривать этот список сокращений, которая имеет две разные интерпретации EDT, 5 различных интерпретаций CST и многие другие конфликты.
Также учтите, что полный идентификатор типа "America/New_York"
точно представляет как EST, так и EDT и обладает всеми знаниями о том, когда следует переходить между ними, включая исторические различия.
В предоставленном вами коде вы запрашиваете у PHP ток смещение для EST и EDT отдельно. Это не имеет смысла, поскольку EDT действует только в течение части года, а EST и EDT не могут действовать одновременно в одном и том же месте. Вместо этого используйте "America/New_York"
смещение и укажите конкретное время, чтобы получить смещение в это время.
Если вам просто нужны стандартные и дневные смещения для каждой зоны, вы можете проверить полночь 1 января и 1 июля текущего года. Все, что ниже, является стандартным смещением. Если они одинаковы, то (обычно) часовой пояс не использует DST.
Не все часовые пояса, которые PHP DateTimeZone принимает в качестве строки в КТО $timezone
Параметр действительно имеет стабильное смещение UTC. Технически говоря, эти два летнее североамериканское восточное время а также стандартное восточное время, не реальные часовые пояса, часовой пояс Восточный часовой пояс (ET) который US / Eastern или же Америка / Триатлон в база данных tz и это источник данных PHP DateTimeZone работает на.
+------------------+--------------------+-----------------------------------------+
| string | getName() | offsets |
+------------------+--------------------+-----------------------------------------+
| America/New_York | (America/New_York) | -0500 / -0400 (2012-01-01 / 2012-06-30) |
| US/Eastern | (US/Eastern) | -0500 / -0400 (2012-01-01 / 2012-06-30) |
| EDT | (EDT) | -0500 / -0500 (2012-01-01 / 2012-06-30) |
| EST | (EST) | -0500 / -0500 (2012-01-01 / 2012-06-30) |
+------------------+--------------------+-----------------------------------------+
Так что особенно эти двое летнее североамериканское восточное время а также стандартное восточное время в моем вопросе не работают, потому что они представляют собой стандартное и летнее время, в то время как PHP DateTimeZone действительно представляет оба. Поэтому смещение UTC неоднозначно. PHP ручные документы что они принимаются только по причинам обратной совместимости, и их не следует использовать с DateTimeZone учебный класс. Пользовательская заметка на странице хорошо говорит:
Не используйте «EST», по крайней мере, в PHP 5.3.3 это то же самое, что «EST5EDT», а не строго стандартное время. Единственный надежный способ интерпретации времени как стандартного времени — это использование формата UTC, например:
$dateObject = date_create("2013-06-30 07:00:00-0500");
Это своего рода спецификация, с которой я работаю (4,3. Устаревшие дата и время; RFC2822 p. 32) говорит, что использование этих зон устарело. Я просто надеялся, что мог бы избавить меня от создания карты часовых поясов с UTC:
EDT is semantically equivalent to -0400
EST is semantically equivalent to -0500
CDT is semantically equivalent to -0500
CST is semantically equivalent to -0600
MDT is semantically equivalent to -0600
MST is semantically equivalent to -0700
PDT is semantically equivalent to -0700
PST is semantically equivalent to -0800
Но это не такой большой список.