它看起来像一个错误(或者至少是一个无证限制) 与 PHP...如果我们尝试 4 种可能的空格排列:
var_dump(\DateTime::createFromFormat('Y-m-dTH:i:s', '2012-01-24MSK16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-d T H:i:s', '2012-01-24 MSK 16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-d TH:i:s', '2012-01-24 MSK16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-dT H:i:s', '2012-01-24MSK 16:53:52'));
我们得到(测试 PHP 5.3、5.4rc6 和 Trunk):
bool(false)
object(DateTime)#2 (3) {
["date"]=>
string(19) "2012-01-24 16:53:52"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}
bool(false)
object(DateTime)#3 (3) {
["date"]=>
string(19) "2012-01-24 16:53:52"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}
因此,这似乎表明时区标识符和/或小时对空格敏感......进一步测试:
var_dump(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-01-24 16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-dH:i:s', '2012-01-2416:53:52'));
产生正确的结果。和:
var_dump(\DateTime::createFromFormat('TY-m-d', 'MSK2012-01-24'));
var_dump(\DateTime::createFromFormat('T Y-m-d', 'MSK 2012-01-24'));
Yields:
bool(false)
object(DateTime)#4 (3) {
["date"]=>
string(19) "2012-01-24 01:49:26"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}
所以是的,时区说明符确实对尾随空格敏感......
编辑:它对空格敏感
如果我们看一下解析日期.ctimelib_parse_from_format()25075号线 http://lxr.php.net/xref/PHP_5_4/ext/date/lib/parse_date.c#25075,我们可以看到所有 4 个时区格式的解析方式都是相同的!这意味着解析的格式标识符之间没有任何区别,因此用于解析它们是可以互换的。
仅此一点似乎就足以成为一个错误(或缺乏功能)。但是,让我们看看会发生什么timelib_get_zone() http://lxr.php.net/xref/PHP_5_4/ext/date/lib/parse_date.c#timelib_get_zone当您使用时区标识符时会调用它。好吧,观察一下,我们可以看到我们调用了timelib_lookup_zone() http://lxr.php.net/xref/PHP_5_4/ext/date/lib/parse_date.c#timelib_lookup_zone当不是 GMT 或时间偏移时。
在那里我们发现了这个错误。 768号线timelib_lookup_zone
,我们可以看到它将消耗整个输入字符串,最多可达其中之一\0
(无效的),)
或一个空格:
while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') {
++*ptr;
}
至于修复它,那就有点棘手了。要解决此问题,需要为每个时区重新实现格式解析器。为了T
解析器,这很简单,因为它始终是一个 3 个字母的字符串。但对于其他人来说,这更有趣,因为有可变的字母,因此空白敏感性可能是一个问题。
简而言之,我建议在时区标识符中添加一个尾随空格并完成它......