我有一个问题是从PHP DateTimeZone和底层数据库中获取UTC偏移信息。我接近每个DT / ST对,但通常少一小时(DT)的时区不是。
例如(source):
东部夏令时( EDT ),当观察夏令时(春/夏)时,比世界协调时间晚4小时( UTC-04:00 )。
东部标准时间( EST ),当观察标准时间(秋/冬)时,比世界协调时间晚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));
}
示例输出(full example,我使用PHP 5.6.1RC1):
EDT (EDT) -0500
EST (EST) -0500
这两个时区实际上是示范性的,我也希望与其他时区一起做,但是我不想对偏移进行硬编码,而是希望用PHP来解决这个问题。强> DateTimeZone
当我看到output across multiple PHP versions时,我可能会遇到一个错误,看起来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
并没有摆弄那么深,到目前为止,我觉得它会很好用。
答案 0 :(得分:3)
PHP使用标准IANA tz database。您可以找到支持的时区列表on Wikipedia或in the PHP documentation。
特别是,您会发现像"EST"
这样的值仅用于向后兼容。您可以在this page文档中看到,使用该格式的时区有一个关于不的大红色警告。虽然"EST"
位于已弃用区域列表中,但"EDT"
不是。
通常,时区缩写会使标识符变差,因为模糊性太多。考虑this list of abbreviations,它有两种不同的EDT解释,5种不同的CST解释,以及许多其他冲突。
还要考虑像"America/New_York"
这样的完整标识符准确地表示EST和EDT,并且具有何时在它们之间转换的所有知识 - 包括历史差异。
在您提供的代码中,您要求PHP分别为EST和EDT提供当前偏移量。这没有意义,因为EDT仅在一年中的部分时间生效,并且EST和EDT不能在同一位置同时生效。相反,使用"America/New_York"
偏移量,并提供特定时间来获取当时的偏移量。
如果您只想要每个区域的标准和日光偏移,您可以测试当年1月1日和7月1日的午夜。标准偏移量以较低者为准。如果它们相同,那么(通常)时区不使用夏令时。
答案 1 :(得分:2)
并非所有PHP DateTimeZone在ctor的$timezone
参数中作为字符串接受的时区确实具有稳定的UTC偏移量。从技术上讲,那两个 EDT 和 EST ,不是真正的时区,时区是东部时区( ET )tz database中的美国/东部或 America / New_York ,这是数据源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) |
+------------------+--------------------+-----------------------------------------+
所以特别是我的问题中的那两个 EDT 和 EST 不能正常工作,因为它们分别代表标准和夏令时,而PHP的 DateTimeZone 确实代表两者。因此,UTC偏移是不明确的。 PHP manual documents仅出于向后兼容性原因而接受这些RFC2822 p. 32,并且不应与 DateTimeZone 类一起使用。页面上的用户注释说得很好:
不要使用'EST',至少在PHP 5.3.3中它与'EST5EDT'相同,而不是严格的标准时间。我发现将时间解释为标准时间的唯一可靠方法是使用UTC相对格式,例如:
$dateObject = date_create("2013-06-30 07:00:00-0500");
这也是我使用的规范( 4.3。过时的日期和时间; {{3}})所说的,使用这些区域已经过时了。我只是希望我能够免费为UTC-offset地图创建一个时区:
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
但这不是一个很大的名单。