Reputation: 1216
I'm connecting to an JSON event API that returns schedule information in ISO8601 format.
"schedule": [
{
"datetime": "2014-06-02T19:30:00-04:00",
"speaker": "Keith Moore"
},
{
"datetime": "2014-06-03T19:30:00-04:00",
"speaker": "Phyllis Moore"
]
When I echo date("c", strtotime($schedule[$j]["datetime"]));
I get 2014-06-02T18:30:00-05:00. Of course, that makes sense since date()
uses the server's time zone.
If I pass a time zone to date()
, or use date_default_timezone_set
), then it should fix things up. Unfortunately, there is no specification as to what the time zone is in ISO8610 (just the offset). If I try and get the time zone from the ISO8601 date, using date()
, then the time zone goes back to the server's.
What I want to do is show the date/time/time zone that's local to the event (Eastern Daylight Time, in this instance). Is there a way to do this?
A couple options that I have thought of, but neither seems appropriate...
Since I have control over the API, I could send the schedule information in RFC 822 format (Mon, 02 Jun 2014 19:30:00 EDT). That would give me hooks that I could do...
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");
...but ISO8601 just seems like a more appropriate format.
On the other hand, I could do some overly-complex array where I specify every possible date/offset combination with a time zone. That, definitely, seems like too much work.
Upvotes: 3
Views: 6903
Reputation: 1216
The answers that were given, while good and very helpful, still left too many exceptions that weren't accounted for (outputting the wrong time zone abbreviation, even though the offset is the same).
Since I have control of the API, I simply included a time zone field.
"schedule": [
{
"datetime": "2013-08-02T18:30:00-05:00",
"timezone": "CDT",
"speaker": "Happy Caldwell"
}
]
Then, when consuming that data, I simply did a comparison and set the server to that time zone.
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");
Now, I'm sure there is a much better way to do this (probably with DateTime
). Feel free to comment on better ways to perform the same function. This does do what was needed, though.
Of course, this doesn't help someone that ONLY has the time zone offset. In those instances, you may have to use one of the other answers and just deal with the exceptions.
Upvotes: -1
Reputation: 14091
You should use PHP's DateTime. Since ISO8601 is an international standard, PHP supports it. The code you need is the following:
$dt = DateTime::createFromFormat(DateTime::ISO8601, '2014-06-03T19:30:00-04:00');
You can specify the third parameter, a DateTimeZone object which you can use to further offset the given date.
For example, if you wanted to use GMT -4 to be GMT
$dt = DateTime::createFromFormat(DateTime::ISO8601, '2014-06-03T19:30:00-04:00', new DateTimeZone('Europe/London'));
And after that, all that's left is:
echo $dt->format('d.m.Y, H:i:s'); // format is the same as for date() function.
Upvotes: 6