PHP转换毫秒到日期失败特定毫秒(1425318722000)

时间:2015-04-24 09:06:02

标签: php date milliseconds

所以我试图在PHP中将毫秒转换为日期,我认为我的脚本工作正常,但是对于特定的毫秒值(1425318722000)会出现奇怪的行为。

我已在几个网站上检查了这一点,并且所有网站都返回了有效值...

2015年3月2日星期一下午5:52:02 GMT

2015年3月2日星期一17:52:02

2015年3月2日星期一17:52:02 GMT + 0000(GMT)

周一,2015年3月2日17:52:02 GMT

任何想法为什么会发生这种情况,这可能是一个PHP错误吗?

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318721999/1000));"
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2015-03-02 17:52:01"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318722000/1000));"
bool(false)

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318722001/1000));"
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2015-03-02 17:52:02"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318722002/1000));"
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2015-03-02 17:52:02"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318722003/1000));"
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2015-03-02 17:52:02"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318722004/1000));"
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2015-03-02 17:52:02"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

php -r "var_dump(DateTime::createFromFormat('U.u', 1425318722005/1000));"
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2015-03-02 17:52:02"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

1 个答案:

答案 0 :(得分:3)

事实上你正在使用'U.u'掩码,但当结果为该分割的小数后面的全部0时,.u会从值中丢失

for($ms = 1425318721999; $ms <= 1425318722001; ++$ms) {
    var_dump(DateTime::createFromFormat('U.u', sprintf('%14.3f', $ms/1000)));
}

会工作,因为你正在使用sprintf()强制在小数点后保留这些零

for($ms = 1425318721999; $ms <= 1425318722001; ++$ms) {
    var_dump(DateTime::createFromFormat('U', floor($ms/1000)));
}

也可以,但你会失去毫秒精度

通过一些解释:

public static DateTime DateTime::createFromFormat ( string $format , string $time [, DateTimeZone $timezone ] )

createFromFormat()期望一个字符串作为第二个参数,因此PHP将您的除法结果强制转换为字符串,而1425318722.000之类的浮点值将强制转换为{{1}字符串1}}没有小数点或跟随零,因此它不符合需要小数点和后续数字的"1425318722"掩码