【问题标题】:Overlapping of two date/time ranges - PHP两个日期/时间范围的重叠 - PHP
【发布时间】:2017-06-08 09:37:00
【问题描述】:

我正在尝试确定两组日期/时间范围是否重叠 --- 返回 BOOLEAN 值。

考虑以下情况:

注意:我使用strtotime()将下面的每个日期/时间字符串(例如24-JAN-17 07:00)转换为时间戳

用于每种情况的表达式是: $isOverlapping = (s1 < e2 && s2 < e1)

案例 1

Let (s1, e1) be defined as (24-JAN-17 07:00, 24-JAN-17 17:00)

Let (s2, e2) be defined as (24-JAN-17 16:30, 24-JAN-17 17:30)

结果: TRUE (这是正确的)


案例 2

Let (s1, e1) be defined as (24-JAN-17 07:00, 24-JAN-17 17:00)

Let (s2, e2) be defined as (24-JAN-17 16:30, 25-JAN-17 07:00)

结果: TRUE (这是正确的)


案例 3

Let (s1, e1) be defined as (24-JAN-17 07:00, 24-JAN-17 17:00)

Let (s2, e2) be defined as (24-JAN-17 17:00, 25-JAN-17 07:30)

结果: FALSE (不正确)


据我了解,它这样做是因为(在上面#3 的情况下),它会溢出到第二天......但如果是这样的话,为什么它对Case 2 有效? (是不是因为重叠发生在同一天,与Case 3相反?)

无论如何,我的问题是,如何调整我的表达方式,使其涵盖上面的案例 3?

任何和所有的帮助表示赞赏!谢谢!


我已经查看了以下主题,但无济于事:

Determine Whether Two Date Ranges Overlap

Determining if two time ranges overlap at any point(具体为:https://stackoverflow.com/a/13387860/7458905

【问题讨论】:

  • 你的问题是日期是相等,所以把这个条件添加到你的逻辑中:$isOverlapping = (s1 <= e2 && s2 <= e1)
  • @Kaylined - OP 已经提到已经审查了确切的问答......

标签: php logic


【解决方案1】:

您也可以使用一些简单的数学来完成此操作。

这里我们简单地将组件分解为它们的 unix 时间戳,然后使用两者的 dx/dy 来确定它们是否重叠

<?php
function is_overlapping($date_range_1, $date_range_2) {

    // convert into unix timestamp (milliseconds since Jan 1st 1970)
    $d1_1 = make_timestamp($date_range_1[0]);
    $d1_2 = make_timestamp($date_range_1[1]);
    $d2_1 = make_timestamp($date_range_2[0]);
    $d2_2 = make_timestamp($date_range_2[1]);

    // grab the delta of both ranges
    $delta2 = $d2_1 - $d1_2;
    $delta1 = $d2_2 - $d1_1;

    // if either has a delta < 0 then they overlap
    if (($delta2 < 0) || ($delta1 < 0)) { return "true"; }

    // catchall return value
    return "false";
}

// convert to unix timestamp function
function make_timestamp($inp_date) { 
    return strtotime($inp_date);
}

// test cases
print_r("Case 1: " .
        is_overlapping(array("24-JAN-17 07:00", "24-JAN-17 17:00"), 
                       array("24-JAN-17 16:30", "25-JAN-17 17:30"))
       );

print_r("<br>");

print_r("Case 3: " .
        is_overlapping(array("24-JAN-17 07:00", "24-JAN-17 17:00"), 
                       array("24-JAN-17 17:30", "25-JAN-17 18:30"))
       );
?>

【讨论】:

    【解决方案2】:

    您的最后一个案例没有返回 TRUE 的原因是由于相等性。

    你说的情况3:

    Let (s1, e1) be defined as (24-JAN-17 07:00, 24-JAN-17 17:00)
    
    Let (s2, e2) be defined as (24-JAN-17 17:00, 25-JAN-17 07:30)
    

    这意味着e1 等于 s2(它们都是 24-JAN-17 17:00)

    但你的逻辑只有在 s2 &lt; e1 时才成立,在这种情况下不成立。

    修改你的逻辑,如果它们相等则返回 true:

    $isOverlapping = (s1 <= e2 && s2 <= e1)
    

    【讨论】:

    • 感谢 Cale 的回复...如果是边缘情况,我不希望它返回 true...换句话说,重叠(根据我的要求)可以返回 false,如果结束时间与开始时间相同(反之亦然)。考虑以下情况:Let (s1, e1) be defined as (24-JAN-17 07:00, 24-JAN-17 17:00)Let (s2, e2) be defined as (24-JAN-17 06:30, 24-JAN-17 07:00) 根据我的需要,这不应算作重叠
    • 那么你的案例#3 应该返回 FALSE?因为它是匹配的,所以它们不会重叠。
    • 在我的情况 3 中,重叠发生在 e2 进入半小时到 s1 时(在第二天,更具体地说)
    • 不,您的案例 3 有零重叠。仔细看。
    • Arrgggg...我的错误。我需要把它算作重叠,因为s1 现在将是25-JAN-17 07:00(抱歉。对我来说,这是一个可以理解的假设,没有意识到不是每个人都会做出这个假设)
    猜你喜欢
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2015-06-25
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多