使用PHP判断DateTime是否在DateInterval范围内

6
我正在尝试确定一个DateTime是否与可能出现的DateInterval恰好重合。我使用的间隔需要允许'下个月的第N个X日'类型的格式规范,但我不确定在这些条件下是否可能实现这样的事情。
我的基本想法是反转DateInterval,将其应用到原始DateTime的克隆中,再将其放回原处,再次应用并检查两个DateTime实例是否相等。如果相等,则表示它恰好处于该间隔上:
public static function dateFallsOnPeriod(DateTime $date, DateInterval $interval)
{
    $compare = clone $date;

    // invert the period, apply it to the date, uninvert & then reapply
    $interval->invert = 1;
    $compare->add($interval);
    $interval->invert = 0;
    $compare->add($interval);

    return $date == $compare;
}

这似乎在同一方向上两次应用间隔,因此我尝试使用->sub()->add()再次尝试,结果出现致命错误“DateTime :: sub():仅支持非特殊相对时间规范进行减法”。看起来这种功能根本没有实现。
有没有更好的想法? 除了选择一个远在开始日期之前的偏移量并向前迭代,直到我们匹配它或超过它,这种方法既丑陋又低效?
提前致谢!

1
invert执行了一个子程序,我测试过它。你的子程序和加法互相抵消了。在开头它检查$compare == $date。 反转(invert)执行子例程,我测试了它。 您的子例程和添加操作相互抵消。 在开头,它检查$compare == $date。 - DevZer0
你能用一个例子来澄清问题吗?让我困惑的是,你的函数名称表明你想查看一个句点是否与日期相符,但你将 DateTime 和 DateInteral 传递到函数中,而不是 - 如我所预期的 - DateTime 和 DatePeriod? - luttkens
我想这个方法应该叫dateCoincidesWithInterval或者类似的名字,抱歉造成困扰。 @DevZer0:添加、减去和比较不总是互相抵消的原因是由于PHP允许一些特殊的间隔。所以如果你的间隔指定为“每月第一个星期天”,而你将星期一作为$date传递进去,你就需要知道那个日期并不符合间隔条件。对于更常见的间隔,你所说的是正确的,这个方法其实并不需要,但是我想用这个方法来涵盖所有可能的情况。 - pospi
你如何在DateInterval中指定“每月第一个星期日”?据我所见,它采用的是一个间隔的绝对度量而不是文字字符串。 - DevZer0
1
@pospi 好的,但我仍然觉得关于DateInterval和DatePeriod存在混淆。DateInterval只是一个“长度”,没有开始和结束日期,与DatePeriod相反。因此,确定日期是否与间隔重合是没有意义的。但对于DatePeriod来说就有意义了。但我认为你不仅仅想确定日期是否在某个时间段内?从你的例子“每月第一个星期天”中,我理解你想要尝试查看日期是否符合任意标准,例如“每月第一天”,“一天中的第三个小时”或“每月第二个星期三”。正确吗? - luttkens
正确!与 PHP 暴露的 DateInterval 相比,本地存在更多的操作。请查看 DatePeriod 用户贡献文档中的此示例。使用周期和这样的间隔将为您提供两个日期之间每个月的最后一个星期四。问题在于,当您使用这样构建的 DateInterval 且您的开始日期不与间隔重合时,它仍然会被包含在 DatePeriod 中。您可以使用“排除开始日期”标志,但是当它确实重合时,您将错误地将其折扣。 - pospi
2个回答

0

我同意tuxnani的观点,使用strtotime()将所有日期转换为Unix格式会更容易,然后只需使用更多或更少的操作比较数字值。


0
一种可能性是从日期时间生成Unix时间戳,然后比较整数值。

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