gpt4 book ai didi

php - 日期时间格式和时区

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:56:58 25 4
gpt4 key购买 nike

当尝试使用 DateTime::createFromFormat 解析日期时,PHP 将无法识别时区。

例子:

$t = new \DateTime(); 
echo $t->format('Y-m-dTH:i:s');

会输出

2012-01-24MSK16:53:52

现在,当我尝试从相同格式解析该字符串时

var_dump(\DateTime::createFromFormat('Y-m-dTH:i:s', '2012-01-24MSK16:53:52'));

我明白了

bool(false)

当我不将时区放入字符串时,它会起作用

$t = new \DateTime(); 
echo $t->format('Y-m-dH:i:s');

会给予

2012-01-2417:17:24

然后解析

var_dump(\DateTime::createFromFormat('Y-m-dH:i:s', "2012-01-2417:17:24"));

会给予

object(DateTime)#3 (3) {
["date"]=>
string(19) "2012-01-24 17:17:24"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Moscow"
}

测试于

  • 带有 Suhosin-Patch (cli) 的 PHP 5.3.6-13ubuntu3.3(构建时间:2011 年 12 月 13 日 18:18:37)和
  • PHP 5.3.9 (cli)(构建时间:2012 年 1 月 18 日 20:02:33)

只要我们注意时区就会出现问题。这是一个错误吗?或者我做错了什么?提前致谢!

最佳答案

它看起来像是 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'));

产量:

bool(false)
object(DateTime)#4 (3) {
["date"]=>
string(19) "2012-01-24 01:49:26"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}

所以是的,时区说明符确实对尾随空格敏感......

编辑:它对空格敏感

如果我们看parse_date.c timelib_parse_from_format() on line 25075 ,我们可以看到所有 4 种时区格式都以相同的方式解析!这意味着用于解析的格式标识符之间没有任何区别,因此用于解析它们是可以互换的。

仅此一项似乎就足以导致继续存在错误(或缺少功能)。但是,让我们看看 timelib_get_zone() 中发生了什么当您使用时区标识符时调用。好吧,往下看,我们可以看到我们调用了timelib_lookup_zone()当它不是 GMT 或时间偏移时。

然后我们发现了错误。在 timelib_lookup_zone 的第 768 行,我们可以看到它将消耗整个输入字符串,直到 \0 (null)、) 之一或空格:

while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') {
++*ptr;
}

关于修复它,这有点棘手。要解决此问题,需要为每个时区重新实现格式解析器。对于 T 解析器,这很容易,因为它始终是 3 个字母的字符串。但对于其他人来说,它更有趣一点,因为有可变字母,因此空格敏感性可能是一个问题。

简而言之,我建议只在您的时区标识符中添加一个尾随空格并完成它...

关于php - 日期时间格式和时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8987782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com