PHP DateInterval 是否与 DateTime 相当?

2022-08-30 14:37:45

我发现PHP中的DateTime对象可以与另一个对象进行比较,因为“>”和“<”运算符被重载。

它与DateInterval相同吗?

当我试图回答这个问题时,我发现了一些奇怪的东西:

<?php 

$today = new DateTime();
$release  = new DateTime('14-02-2012');
$building_time = new DateInterval('P15D');
var_dump($today->diff($release));
var_dump($building_time);
var_dump($today->diff($release)>$building_time);
var_dump($today->diff($release)<$building_time);
if($today->diff($release) < $building_time){
    echo 'oK';
}else{
    echo 'Just a test';
}

它总是呼应“只是一个测试”。var_dump输出是:

object(DateInterval)#4 (8) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(18)
  ["h"]=>
  int(16)
  ["i"]=>
  int(49)
  ["s"]=>
  int(19)
  ["invert"]=>
  int(1)
  ["days"]=>
  int(18)
}
object(DateInterval)#3 (8) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(15)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["invert"]=>
  int(0)
  ["days"]=>
  bool(false)
}
bool(false)
bool(true)

当我尝试将DateTime作为“01-03-2012”时,一切正常。


答案 1

简而言之,默认情况下目前不支持对象比较(从 php 5.6 开始)。DateInterval

如您所知,对象是可比较的。DateTime

实现所需结果的一种方法是从对象中减去或添加,并比较两者以确定差异。DateIntervalDateTime

示例:https://3v4l.org/kjJPg

$buildDate = new DateTime('2012-02-15');
$releaseDate = clone $buildDate;
$releaseDate->setDate(2012, 2, 14);
$buildDate->add(new DateInterval('P15D'));

var_dump($releaseDate < $buildDate); //bool(true)

编辑

从 PHP 7.1 发布开始,由于增加了对微秒的支持,结果与 PHP 5.x 不同。

示例:https://3v4l.org/rCigC

$a = new \DateTime;
$b = new \DateTime;

var_dump($a < $b);

结果 (7.1+)

bool(true)

结果 (5.x - 7.0.x, 7.1.3)

bool(false)

若要避免此行为,建议您改为使用 来比较对象。cloneDateTime

示例:https://3v4l.org/CSpV8

$a = new \DateTime;
$b = clone $a;
var_dump($a < $b);

结果 (5.x - 7.x)

bool(false)

答案 2

看起来有一个相关的错误/功能请求,不确定它是否曾经在主干中出现过。无论哪种方式都没有记录(我能找到) - 所以使用起来可能不安全。

也就是说,经过一些测试,似乎可以比较它们,但只有在以某种方式“评估”它们之后(执行var转储会改变结果)。这是我的测试/结果:

<?php
$int15 = new DateInterval('P15D');
$int20 = new DateInterval('P20D');

var_dump($int15 > $int20); //should be false;
var_dump($int20 > $int15); //should be true;

var_dump($int15 < $int20); //should be true;
var_dump($int20 < $int15); //should be false;

var_dump($int15);
var_dump($int20);

var_dump($int15 > $int20); //should be false;
var_dump($int20 > $int15); //should be true;

var_dump($int15 < $int20); //should be true;
var_dump($int20 < $int15); //should be false;

$date = new DateTime();
$diff = $date->diff(new DateTime("+10 days"));

var_dump($int15 < $diff); //should be false;
var_dump($diff < $int15); //should be true;

var_dump($int15 > $diff); //should be true;
var_dump($diff > $int15); //should be false;

var_dump($diff);

var_dump($int15 < $diff); //should be false;
var_dump($diff < $int15); //should be true;

var_dump($int15 > $diff); //should be true;
var_dump($diff > $int15); //should be false;

结果(我省略了间隔对象的完整转储):

bool(false)
bool(false)
bool(false)
bool(false)
object(DateInterval)#1 (8) {...}
object(DateInterval)#2 (8) {...}
bool(false)
bool(true)
bool(true)
bool(false)

bool(false)
bool(true)
bool(true)
bool(false)
object(DateInterval)#5 (8) {...}
bool(false)
bool(true)
bool(true)
bool(false)

推荐