我正在连接到一个JSON事件API,它返回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中的时区(只是偏移量)。如果我尝试使用date()
从ISO8601日期获取时区,则时区将返回服务器。
我想要做的是显示事件的本地日期/时间/时区(在本例中为东部夏令时)。有没有办法做到这一点?
我想到的几个选项,但似乎都不合适......
由于我可以控制API,因此我可以以RFC 822格式发送日程安排信息(星期一,2014年6月2日19:30:00美国东部时间)。这会给我一些我可以做的钩子......
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似乎是一种更合适的格式。
另一方面,我可以做一些过于复杂的数组,我用时区指定每个可能的日期/偏移量组合。当然,这似乎太过分了。
答案 0 :(得分:4)
你应该使用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.
答案 1 :(得分:-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
)。随意评论更好的方法来执行相同的功能。不过,这确实可以做到。
当然,这对那些只有时区偏移的人没有帮助。在这些情况下,您可能必须使用其他答案之一并处理异常。