2

我正在连接到以 ISO8601 格式返回日程信息的 JSON 事件 API。

"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(),则时区将返回到服务器的。

我想要做的是显示事件本地的日期/时间/时区(在这种情况下为东部夏令时间)。有没有办法做到这一点?

我想到了几个选项,但似乎都不合适......

由于我可以控制 API,我可以发送 RFC 822 格式的日程安排信息(星期一,2014 年 6 月 2 日 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 似乎是一种更合适的格式。

另一方面,我可以做一些过于复杂的数组,在其中我指定每个可能的日期/偏移组合与时区。毫无疑问,这看起来工作量太大了。

4

2 回答 2

5

您应该使用 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.
于 2013-07-30T15:35:42.253 回答
-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)。随意评论执行相同功能的更好方法。不过,这确实可以满足需要。

当然,这对只有时区偏移的人没有帮助。在这些情况下,您可能必须使用其他答案之一并仅处理异常。

于 2013-07-31T16:27:25.510 回答