DateInterval 不接受带毫秒的 ISO 8601 时间段。

4
我有一个 ISO 8601 时间段字符串:P0Y0M0DT3H5M0.000S,但 PHP7.4 无法使用它构建 DateInterval。
<?php
$d = new \DateInterval('P0Y0M0DT3H5M0.000S');
var_dump($d);

致命错误:未捕获的异常:DateInterval :: __construct(): 未知或错误格式(P0Y0M0DT3H5M1.33S)在[...][...]:2

它因毫秒而失败。当我省略毫秒-P0Y0M0DT3H5M0S-时,它可以正常工作。

据我所知,带有毫秒的应该是有效的ISO 8601字符串。
根据维基百科,这是格式:

[Start]P[JY][MM][WW][TD][T[hH][mM][s[.f]S]]
https://de.wikipedia.org/wiki/ISO_8601#Zeitspannen

为什么PHP不接受这种格式,我该如何解决?

1
PHP已知的漏洞 - DinoCoderSaurus
@DinoCoderSaurus 是的,那似乎是问题所在。 - ivoba
1
似乎更像是一个“被遗忘的漏洞”... - Luuk
1个回答

2
你可以使用 DateInterval::createFromDateString
$d = DateInterval::createFromDateString('3 Hours 5 Minutes 500000 microseconds');

echo $d->format('%h Hours %m Minutes %s.%F Seconds');
//3 Hours 0 Minutes 0.500000 Seconds

以下函数可用作解决方案,如果指定了类似于P0Y0M0DT3H5M7.520S的表达式。
function createDateInterval($interval_spec){
  $f = 0.0;
  if(preg_match('~\.\d+~',$interval_spec,$match)){
    $interval_spec = str_replace($match[0], "", $interval_spec);
    $f = (float)$match[0];
  }
  $di = new \Dateinterval($interval_spec);
  $di->f= $f;
  return $di;
}

$d = createDateInterval('P0Y0M0DT3H5M7.520S');
echo '<pre>';
var_export($d);

结果:

DateInterval::__set_state(array(
   'y' => 0,
   'm' => 0,
   'd' => 0,
   'h' => 3,
   'i' => 5,
   's' => 7,
   'f' => 0.52,
   'weekday' => 0,
   'weekday_behavior' => 0,
   'first_last_day_of' => 0,
   'invert' => 0,
   'days' => false,
   'special_type' => 0,
   'special_amount' => 0,
   'have_weekday_relative' => 0,
   'have_special_relative' => 0,
)) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接