PHP检查两个日期时间是否不在同一天历法上

3
我有两个日期时间,像这样(实际上日期是$vars)
$startTime = \DateTime::createFromFormat('Y/m/d H:i', '2015/01/01 23:00');
$endTime = \DateTime::createFromFormat('Y/m/d H:i', '2015/01/02 01:00');

我在解决一个(可能相当简单的)问题:如何确定两个日期是否在不同的日历天上?
我不能用<来判断,因为2015/01/01 22:00 < 2015/01/01 23:00也是正确的。我也不能这样做:
$diff = $startTime->diff($endTime);
$days = $diff->format('%d');

echo $days;

由于这让我得到了 0这里给了我一个关于如何做到这一点的想法,但是对于JavaScript而言,相当于PHP的是什么呢?

//更新

    $startDate = $startTime->format('Y/m/d');
    $endDate = $endTime->format('Y/m/d');
    $diffDates = $startDate->diff($endDate);
    $daysDiff = $diffDates->format('%d');

    echo $daysDiff;

经过评论,我认为这可能是正确的方法,但现在我得到了 Error: Call to a member function diff() on string 的错误。

//更新以澄清我的意图

我只想知道相差的天数,所以对于上面的例子,它将是 '1' (实际上只有2小时的时间差),例如 '2015/01/01 23:00' 和 '2015/01/03 17:00' 将是 '2'


为什么不使用类似于“Y-m-d”的格式对它们进行格式化并进行比较呢? - jeroen
你想要做什么? - jilesh
我希望上面的例子返回1作为结果,因为这意味着这些日期时间之间相隔一天。 - PrimuS
$isSameCalendarDay = $d1->format('Y-m-d') === $d2->format('Y-m-d') 是否为同一天? - Darragh Enright
你需要在DateTime对象上使用diff(),而不是从format()结果中得到的字符串。 - jeroen
你是否也想用同一段代码计算差异?这没有任何意义,两个日期可能相差1小时并属于同一天,也可能不是。 - Álvaro González
3个回答

3

我认为这是少数几种情况之一,使用字符串进行日期计算是合理的:

function onDifferentDays(\DateTimeInterface $startTime, \DateTimeInterface $endTime){
    return $startTime->format('Y-m-d')!==$endTime->format('Y-m-d');
}

这段代码应该很容易扩展以包括时区。

虽然还有其他替代方法,但我认为它们通常不值得付出努力:

  1. 逐个元素比较(天、月和年):

    • PHP的DateTime类没有专用函数,只有format()
  2. 将两个日期归一化到一个公共时间,并使用==(而不是===)进行比较:

    • 除非您使用的是不可变对象,否则需要克隆输入或期望副作用

    • 您还需要确保时间存在于活动时区中,尽管午夜可能足够安全。

无论如何,因人而异 ;-)


这几乎是我想要的,但是我需要的不是true/false,而是天数,所以2015/01/01 08:00和2015/01/03 17:00会输出2。但我认为我可以自己解决这个问题,所以到目前为止谢谢你! - PrimuS
好的,我不知道你需要什么,但这就是你所要求的 :-? - Álvaro González

3

只需创建时间设置为00:00:00的日期:

$startTime = \DateTime::createFromFormat('Y/m/d H:i:s', '2015/01/01 00:00:00');
$endTime = \DateTime::createFromFormat('Y/m/d H:i:s', '2015/01/02 00:00:00');

或在现有日期上将重置时间归零:

$startTime->setTime(0, 0, 0);
$endTime->setTime(0, 0, 0);

那么它应该可以工作:
$diff = $startTime->diff($endTime);
$days = $diff->format('%d');

echo $days; // 1

奖金

如果你只想处理日期,记得在 createFromFormat 中将时间设置为 00:00:00 或使用 setTime 重置时间。如果在 createFromFormat 中不提供时间,PHP 将使用当前时间设置:

$date = DateTime::createFromFormat('Y-m-d', '2016-01-21');
print $date->format('H:i:s'); //not 00:00:00

要修复它,您必须执行以下操作之一:

  • 提供格式为00:00:00的时间:

    $date = DateTime::createFromFormat('Y-m-d H:i:s', '2016-01-21 00:00:00');

  • 在日期格式前加上感叹号并省略时间,这将自动将时间设置为00:00:00:

    $date = DateTime::createFromFormat('!Y-m-d', '2016-01-21');

  • 创建后重置时间:

    $date = DateTime::createFromFormat('Y-m-d', '2016-01-21'); $date->setTime(0, 0);


“setTime” 是我所缺少的。谢谢! - PrimuS
值得注意的是,计算出的差异并不真实,因为我们不再使用原始时间。 - Álvaro González

2

比较格式化的日期是正确的做法:

$a->format('Y-m-d') === $b->format('Y-m-d')

如果您使用Carbon,可以通过以下方法来实现:
$dt1->isSameDay($dt2)

我建议使用这个链接,而不是之前在这里给出的答案。请访问http://carbondoc/docs/#api-comparison

你能提供一下那个方法的文档链接吗?我找不到它。 - LuckyStarr
比较部分 $dt->isSameDay($dt2); // 同年同月同日 - KyleK
这是一个旧答案,我认为之前问题中有一个“Carbon”标签,但不确定。 - KyleK

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