2013-07-30 3 views
2

Я подключаюсь к API событий JSON, который возвращает информацию о расписании в формате ISO8601.PHP: конвертировать ISO8601 в реальный часовой пояс

"schedule": [ 
{ 
    "datetime": "2014-06-02T19:30:00-04:00", 
    "speaker": "Keith Moore" 
}, 
{ 
    "datetime": "2014-06-03T19:30:00-04:00", 
    "speaker": "Phyllis Moore" 
] 

Когда я echo date("c", strtotime($schedule[$j]["datetime"])); я 2014-06-02T18: 30: 00-05: 00. Конечно, это имеет смысл, так как date() использует часовой пояс сервера.

Если я прохожу часовой пояс до date() или использую date_default_timezone_set), тогда он должен исправить ситуацию. К сожалению, нет спецификации того, что часовой пояс в ISO8610 (только смещение). Если я попытаюсь получить часовой пояс из даты ISO8601, используя date(), тогда часовой пояс вернется к серверу.

Что я хочу сделать, это показать дату/время/часовой пояс, который является локальным для события (в данном случае - Eastern Daylight Time). Есть ли способ сделать это?

пару вариантов, которые я думали, но и не представляется целесообразным ...

Поскольку у меня есть контроль над API, я мог бы послать информацию расписания в RFC 822 формат (пн, 02 июня 2014 19: 30:00 EDT). Это дало бы мне крючки, которые я мог бы сделать ...

if ($pubDatetimezone == "PST" || $pubDatetimezone == "PDT") date_default_timezone_set("America/Los_Angeles"); 
if ($pubDatetimezone == "MST" || $pubDatetimezone == "MDT") date_default_timezone_set("America/Denver"); 
if ($pubDatetimezone == "CST" || $pubDatetimezone == "CDT") date_default_timezone_set("America/Chicago"); 
if ($pubDatetimezone == "EST" || $pubDatetimezone == "EDT") date_default_timezone_set("America/Montreal"); 

... но ISO8601 только кажется, более подходящий формат.

С другой стороны, я мог бы сделать слишком сложный массив, где я указывал каждую возможную комбинацию даты/смещения с часовым поясом. Это, безусловно, похоже на слишком много работы.

+1

Из любопытства вы считали класс PHP DateTime, чтобы помочь вам решить вашу проблему? –

+0

Я не знал, что он существует. Может ли он определить часовой пояс из смещения? – doubleJ

+1

Возможный дубликат [Конвертировать UTC-смещение в часовой пояс или дату] (http://stackoverflow.com/questions/11820718/convert-utc-offset-to-timezone-or-date) – vascowhite

ответ

3

Вы должны использовать PHP DateTime. Поскольку ISO8601 является международным стандартом, PHP поддерживает его. Код нужно следующее:

$dt = DateTime::createFromFormat(DateTime::ISO8601, '2014-06-03T19:30:00-04:00'); 

Вы можете задать третий параметр, объект DateTimeZone, который можно использовать для дальнейшего смещения заданной даты.

Например, если вы хотите использовать GMT -4 быть GMT

$dt = DateTime::createFromFormat(DateTime::ISO8601, '2014-06-03T19:30:00-04:00', new DateTimeZone('Europe/London')); 

И после этого, все, что осталось:

echo $dt->format('d.m.Y, H:i:s'); // format is the same as for date() function. 
+0

Но в этом проблема. Я не знаю, каков фактический часовой пояс. -04: 00 может быть EDT или AST. У меня есть информация о местоположении (Город и штат), но есть несколько штатов, которые содержат два часовых пояса (не говоря уже обо всех зарубежных странах, о которых я понятия не имею. – doubleJ

+1

Объект datetime дает вам смещение '($ dt-> getOffset()) '. Если вам нужен часовой пояс, которому соответствует смещение, используйте что-то вроде' echo timezone_name_from_abbr ("", 3600 * $ dt-> getOffset(), 0); 'должно дать вам что-то значимое. –

+0

' $ dt-> getOffset() 'сделал то, что искал. У него проблема с расписанием в Абудже, Нигерия. У меня есть дата/время' 2013-11-01T18: 00: 00 + 01: 00', и это выводит «Европу/Лондон». Я уверен, что проблема связана с отсутствием летнего времени в West Africa Time. Я мог бы указать переопределение для чего-то неловкого. – doubleJ

-1

ответы, которые были даны, в то время как хорошо и очень полезно, все же осталось слишком много исключений, которые не были учтены (вывод неправильной аббревиатуры часового пояса, хотя смещение одинаково).

Поскольку у меня есть контроль над API, я просто включил поле часового пояса.

"schedule": [ 
{ 
    "datetime": "2013-08-02T18:30:00-05:00", 
    "timezone": "CDT", 
    "speaker": "Happy Caldwell" 
} 
] 

Затем, когда я использовал эти данные, я просто сделал сравнение и установил сервер в этот часовой пояс.

if ($timezone == "HAST" || $timezone == "HADT") date_default_timezone_set("Pacific/Honolulu"); 
if ($timezone == "AKST" || $timezone == "AKDT") date_default_timezone_set("America/Juneau"); 
if ($timezone == "PST" || $timezone == "PDT") date_default_timezone_set("America/Los_Angeles"); 
if ($timezone == "MST" || $timezone == "MDT") date_default_timezone_set("America/Boise"); 
// doesn't observe dst 
if ($state == "AZ") date_default_timezone_set("America/Phoenix"); 
if ($timezone == "CST" || $timezone == "CDT") date_default_timezone_set("America/Chicago"); 
if ($timezone == "EST" || $timezone == "EDT") date_default_timezone_set("America/New_York"); 
// doesn't observe dst 
if ($timezone == "PET") date_default_timezone_set("America/Lima"); 
if ($timezone == "AST" || $timezone == "ADT") date_default_timezone_set("America/Puerto_Rico"); 
// doesn't observe dst 
if ($timezone == "GMT") date_default_timezone_set("Europe/London"); 
if ($timezone == "CET" || $timezone == "CEST") date_default_timezone_set("Europe/Amsterdam"); 
// doesn't observe dst 
if ($timezone == "WAT") date_default_timezone_set("Africa/Lagos"); 

Теперь, я уверен, что есть гораздо лучший способ сделать это (вероятно, с DateTime). Не стесняйтесь комментировать лучшие способы выполнения одной и той же функции. Тем не менее, это делает то, что нужно.

Конечно, это не помогает тому, кто ТОЛЬКО имеет смещение часового пояса.В этих случаях вам, возможно, придется использовать один из других ответов и просто иметь дело с исключениями.

+0

-1, поскольку этот ответ решает проблему OP проблема, но не отвечает на заданный вопрос (да, я знаю, что плакат является OP). Если OP примет или опубликует ответ, который на самом деле отвечает на вопрос, тогда я удалю -1. – dotancohen

+0

Ой ... Я понимаю правила. К сожалению, я не думаю, что есть ответ. Комментарий к исходному сообщению, вероятно, был бы более уместным, но могли ли вы отобразить этот пост кода в комментарии? Хлоп. – doubleJ

Смежные вопросы