使用 PHP 检测日历事件重叠冲突

2024-02-22

我正在开发一项功能,用于检查外部事件是否与内部事件(在日历应用程序中)发生冲突。该过程如下所示:

  • 我的应用程序创建了一系列可能的事件(称为$internalEvents)
  • 我从 Google Calendar、iCloud 等日历(称为$externalEvents)。这些是具有以下类型的现有事件busy.
  • 现在我必须检查内部和外部事件是否存在任何冲突。我尝试了一些方法,如下所示,但到目前为止这是不正确或万无一失的。

我试图尽可能地将其减少到最低限度。这是数据输入:

$internalEvents = array(
    array(
        "start" => "03/29/2016 12:00:00",
        "end" => "03/29/2016 13:00:00"
    ),
    array(
        "start" => "03/29/2016 12:30:00",
        "end" => "03/29/2016 13:30:00"
    ),
    array(
        "start" => "03/29/2016 13:00:00",
        "end" => "03/29/2016 14:00:00"
    ),
    array(
        "start" => "03/29/2016 13:30:00",
        "end" => "03/29/2016 14:50:00"
    ),
    array(
        "start" => "03/29/2016 14:00:00",
        "end" => "03/29/2016 15:00:00"
    ),
    array(
        "start" => "03/29/2016 14:30:00",
        "end" => "03/29/2016 15:30:00"
    ),
    array(
        "start" => "03/29/2016 15:00:00",
        "end" => "03/29/2016 16:00:00"
    ),
    array(
        "start" => "03/29/2016 15:30:00",
        "end" => "03/29/2016 16:30:00"
    ),
    array(
        "start" => "03/29/2016 16:00:00",
        "end" => "03/29/2016 17:00:00"
    )
);

$externalEvents = array(
    array(
        "start" => "03/29/2016 08:00:00",
        "end" => "03/29/2016 12:00:00",
        "type" => "busy"
    ),
    array(
        "start" => "03/29/2016 15:30:00",
        "end" => "03/29/2016 16:00:00",
        "type" => "busy"
    ),
    array(
        "start" => "03/29/2016 13:30:00",
        "end" => "03/29/2016 14:15:00",
        "type" => "busy"
    )
);

现在我尝试通过将内部事件与所有外部事件进行比较来找到任何类型的冲突:

foreach($internalEvents as $internalEvent) {

    $internalEventStart = new DateTime($internalEvent['start']);
    $internalEventEnd = new DateTime($internalEvent['end']);

    $result = true;

    echo "\nverifying " . $internalEventStart->format('Y-m-d H:i') . " - " . $internalEventEnd->format('Y-m-d H:i') . "\n";

    foreach($externalEvents as $externalEvent) {
        $externalEventStart = new DateTime($externalEvent['start']);
        $externalEventEnd = new DateTime($externalEvent['end']);

        // check if there are conflicts between internal and external events
        if ($internalEventStart >= $externalEventStart && $internalEventStart <= $externalEventEnd) {
            $result = false;
            echo "   problem 1: event is between busy time: " . "\n";
        }

        if ($internalEventStart >= $externalEventStart && $internalEventStart <= $externalEventEnd && $externalEventEnd <= $internalEventEnd) {
            $result = false;
            echo "   problem 2: event starts during busy time: " . "\n";
        }

        if ($internalEventStart <= $externalEventStart && $externalEventStart <= $internalEventEnd && $internalEventEnd <= $externalEventEnd) {
            $result = false;
            echo "   problem 3: event stops during busy time: " . "\n";
        }

        if (($internalEventStart <= $externalEventStart) && ($externalEventStart <= $externalEventEnd) && ($externalEventEnd <= $internalEventEnd)) {
            $result = false;
            echo "   problem 4: event during busy time: " . "\n";
        }

        if (($internalEventStart <= $internalEventEnd) && ($internalEventEnd <= $externalEventStart) && ($externalEventStart <= $externalEventEnd)) {
            $result = false;
            echo "   problem 5: event during busy time: " . "\n";
        }
    }

    if($result) {
        echo "   result: OK\n";
    } else {
        echo "   result: NOT OK \n";
    }
}

我正在寻找一种可以发现任何可能的事件重叠冲突的算法。任何提示都将受到高度赞赏。

可以找到运行代码here http://ideone.com/1GbokS(IDEone.com)。


当两个事件发生碰撞时?请参阅此架构:

                              ----E----                 CS/EE   CE/ES
                        --N--                             <       <
                                        --N--             >       >
                           --C--                          <       >
                                     --C--                <       >
                                --C--                     <       >
                             -----C-----                  <       >
                    ··················································
                    E  = Main Event
                    N  = Not Collide Event
                    C  = Collide Event
                    CS = Compare Event Start
                    EE = Main Event End
                    CE = Compare Event End
                    ES = Main Event Start

正如您所看到的,只有当事件 C 的开始早于事件 E 的结束并且事件 E 的结束晚于事件 C 的开始时,才会发生冲突。了解这一点有助于找到一种高效且简短的方法来比较事件。

关于代码,初步说明:您在代码中多次比较日期之前先转换 ISO 8601 中的日期,那么为什么不为此创建一个函数呢?

function eventsToDate( $row )
{
    $retval = array( 'start' => date_create( $row['start'] )->format('Y-m-d H:i:s'), 'end' => date_create( $row['end'] )->format('Y-m-d H:i:s') );
    $retval['print'] = sprintf( '%s-%s', substr( $retval['start'],-8,5 ), substr( $retval['end'],-8,5 ) );
    return $retval;
}

此函数返回一个以您的格式包含“start”和“end”的关联数组。我添加了第三个键“打印”,以在调试期间使用。请注意,在打印中我只考虑小时:分钟(数组样本中的所有日期都来自同一天),但比较是在完整日期上进行的。您可以省略此“打印”键或将其替换为首选输出格式。

你执行两个嵌套的foreach,并为每个循环重新计算日期格式。对于数组样本,您调用 DateTime/DateTime::format 36 次。通过创建一个包含所有已转换的临时数组$externalEvents,我们可以将这些调用减少到 12 个。所以,在开始之前foreach()循环,我们使用array_map具有上述自定义功能和$externalEventsarray 创建具有格式化日期的数组:

$externalDates = array_map( 'eventsToDate', $externalEvents );

然后我们开始主要的foreach()循环播放$internalEvents:

foreach( $internalEvents as $internalEvent )
{
    $internalDates = eventsToDate( $internalEvent );

    echo $internalDates['print'] . PHP_EOL;
    $result = True;
    foreach( $externalDates as $externalDate )
    {

此时,我们比较日期。如上所述,我们比较 start 与 end 以及 end 与 start。为了简化接下来的比较,我们使用strcmp,一个 php 函数,“如果 str1 小于 str2,则返回 0;如果相等,则返回 0”:

        $startCmp = strcmp( $internalDates['start'], $externalDate['end'] );
        $endCmp   = strcmp( $internalDates['end'],   $externalDate['start']   );

现在,比较一下:

        if( $startCmp<0 && $endCmp>0 )
        {
            $result = False;
            echo "           {$externalDate['print']} COLLIDE\n";
        }
        else
        {
            echo "           {$externalDate['print']} OK\n";
        }
    }

最后,我们可以打印结果:

    echo "Result: " . ( $result ? 'OK' : 'NOT OK') . "\n\n";
}

eval.in demo https://eval.in/541934

注:与上面的比较,与第一个$internalEvent我们得到以下结果:

12:00-13:00
           08:00-12:00 OK
           15:30-16:00 OK
           13:30-14:15 OK
Result: OK

相反,如果你想要这个结果:

12:00-13:00
           08:00-12:00 COLLIDE
           15:30-16:00 OK
           13:30-14:15 OK
Result: NOT OK

你必须更换上面if条件与此:

         if( $startCmp<=0 && $endCmp>=0 )

上面的代码可以工作,如果您想了解有关碰撞类型的更多详细信息,您可以在内部测试开始/结束的其他组合if健康)状况。


替代方案:返回碰撞事件

如果您想要捕获碰撞事件而不是打印结果,则可以替换嵌套foreach() with array_filter这样:

$result = array_filter
(
    $externalDates, 
    function( $row ) use( $internalDates )
    {
        $startCmp = strcmp( $internalDates['start'], $row['end'] );
        $endCmp   = strcmp( $internalDates['end'],   $row['start']   );
        return( $startCmp<0 && $endCmp>0 );
    }
);

此时,碰撞事件已在数组中$result。显然,如果数组为空,则不存在碰撞。


  • 阅读更多关于strcmp() http://php.net/manual/en/function.strcmp.php
  • 阅读更多关于数组映射() http://php.net/manual/en/function.array-map.php
  • 阅读更多关于数组过滤器() http://php.net/manual/en/function.array-filter.php
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PHP 检测日历事件重叠冲突 的相关文章

  • 如何使 laravel Blueprints 变形方法在指定列后添加列

    在创建迁移脚本时我可以做这样的事情 Schema table books function Blueprint table table gt string reference gt after access 这将在访问列之后创建我的参考列
  • 为什么在发出带有发布数据的请求后,PHP 中的 $_POST 数组为空

    我使用发布数据向页面 getremote php 发出发布请求 但 POST 数组似乎为空 如果有人能告诉我我做错了什么 我将不胜感激 发出请求的 JavaScript 代码是 var postdata Content Type appli
  • 显示文件夹并建立这些文件夹的链接

    我正在寻找用 PHP 构建一个目录浏览器 我刚刚开始编写代码 但需要有人帮助我完成或修改它 dir dirname FILE path of the directory to read iterator new RecursiveDirec
  • PHP 查找最接近时间线期间的日期

    所以 呃 好吧 这可能会涉及到数学问题 所以希望你带上科学计算器 这是我的问题 给定初始日期 时间戳 时间段 秒 和今天的日期 时间戳 我需要找到与 period n 加上原始 初始日期一致的最近日期 到目前为止 我得到了一些运行良好的东西
  • 在 php 中检测 iPad?

    如何向 iPad 查看者提供不同的页面 if SERVER HTTP USER AGENT Mozilla 5 0 iPad U CPU iPhone OS 3 2 like Mac OS X en us AppleWebKit 531 2
  • 如何检查 id 是否已存在 - codeigniter

    我正在尝试检查数据库中的 id 是否已存在 如果不存在则仅插入该 id 而不是其他存在的 id 我尝试执行一个 where 语句来检查数据库中是否存在它们的 id 但即使它们是新信息 它也不会将其插入数据库中 我在这里很迷路 任何指导将不胜
  • Python:如何转换日期时间格式? [复制]

    这个问题在这里已经有答案了 可能的重复 如何将时间转换为字符串 https stackoverflow com questions 4855406 how to convert a time to a string I have a变量如下
  • ruby 中可以做动态变量吗? [复制]

    这个问题在这里已经有答案了 我可以通过其他方式实现这种动态性质 但这引起了我的好奇 Ruby 中有类似的机制吗 varname hello varname world echo hello Output world 您可以使用以下方法实现类
  • 在 eclipse pdt 中同步时 - 比较 php 文件的版本时出现空白灰色窗口

    我已经安装了适用于 64 位 Linux 的 Eclipse PDT Helios SR1 GTK Ubuntu Maverick 全新安装 我添加了用于使用 Subversion 的 Subversive 插件 并安装了 SVNKit 1
  • XAMPP 中的根路径

    我遇到这个问题已经有一段时间了 并且广泛寻找答案但没有成功 img src images test jpg 从 根路径 在我的例子中是在 LAMP 中的生产中 获取图像 htdocs images test jpg 无论是从 htdocs
  • 如何使用 php 命令使注册表单高度安全?

    我想让代码对用户来说真正安全 下面的代码显示了 php 代码 我已将其用于我的网站 现在我已经使用了一些验证 例如密码和重复密码必须匹配 并且用户必须输入所有字段 为了使其更安全 我想插入安全命令 例如 PDO mysqli crypto
  • PHP:数据库连接类构造方法

    我是面向对象编程的新手 最初 我是在类内部和构造函数外部定义变量并为其赋值 但是在今天的 Java OOP 课程之后 我被告知这是不好的风格 应该避免 这是我模拟的原始 PHP 数据库连接类 class DatabaseConnection
  • URL 重写 OpenCart 产品 SEO

    我想重写我的 opencart 网上商店的产品网址 Opencart 本身有一个 seo 实现 这真的很糟糕 我已经更新了 seo 实现 以便能够对多个类别使用相同的关键字 请参阅 Opencart 重复 URL 关键字 https sta
  • 在 Java 和 PHP 之间加密/解密字符串

    我使用 AES 加密来加密和解密服务器端的 php 和 Android 应用程序 作为客户端 之间的字符串 PHP 中的加密字符串为 HaxRKnMxT24kCJWUXaVvqDHahzurJQK sYA4lIHql U 在 Java 中是
  • 删除删除线的 unicode 文本?

    我偶尔会收到用户的输入 他们正在使用那些烦人的 stikethrough 文本生成器 这破坏了我的代码 我尝试过在这里找到的一些代码 string preg replace x00 x1F x80 xFF string 它有效 但我需要它只
  • PHP:分离业务逻辑和表示逻辑,值得吗? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么要在 PHP 中使用模板系统 https stackoverflow com questions 436014 why should i use templating system in php
  • WooCommerce 添加到购物车后停止重定向

    我希望在用户单击 添加到购物车 按钮后完全删除任何重定向 实际上我没有使用产品页面 我使用一个带有产品链接的简单按钮 如下所示 add to cart 492 我的用户将单击我页面上的多个 添加到购物车 按钮 因此在单击第一个按钮后他无法重
  • 一个模型中的多个表 - Laravel

    我的索引页使用数据库中的 3 个表 索引滑块 索引特征 页脚框 我使用一个控制器 IndexController php 并像这样调用三个模型 public function index return View make index gt
  • 使用 jQuery 将值发送到 $_GET

    我正在使用一个 PHP 脚本 该脚本正在通过 GET 等待两个值 我正在尝试使用 jQuery 传递这两个值 而这正是我不太擅长的地方 这是我得到的代码 有人能指出我正确的方向吗 谢谢 function xrate id rating aj
  • 寻求有关标记视频系统上的“相关视频”查询的建议

    好吧 我运行一个小型视频网站 在实际的视频页面上有一条与大多数视频页面 例如 YouTube 类似的 相关视频 目前我所做的就是随机获取其标签之一并查找其他视频相同的标签 毫不奇怪 这不是一个好方法 因为有些标签非常模糊 有些视频被错误标记

随机推荐

  • Sprite Kit:大量带有 Bit Blitting 的 sprite(1000+)

    我正在尝试使用 SpriteKit 创建一个场景 其中包含数千个精灵 500 2000 每个精灵只是一个 1x1 的白色像素 甚至不需要为它们使用纹理 立即将这么多精灵直接添加到场景中是不可能的 或者至少我这么认为 在 iPhone 6 上
  • 玩法框架2:在route中使用Array[String]

    我想生成一个像这样的网址 照片 标签 标签1 标签2 标签3 路线文件 GET photo controllers Photos list tags Array String 我在播放控制台中收到此错误 找不到 Array String 类
  • 尝试使用 ServiceController 时出现错误 MSB4062

    我在 x64 计算机上使用 Visual Studio 2010 和 TFS 2010 我正在尝试在我的构建中使用 MSBuild 社区任务目标 该目标存在于源代码管理中 因此 在我的 csproj 文件中 我导入该特定目标 但现在出现以下
  • 在项目的层次结构中找不到新元素

    我正在尝试为 Xamarin 应用程序创建一个简单的页面 但完全无法继续执行最基本的步骤 我从项目存储库中检查分支 并尝试添加新文件 当我这样做时 右键单击文件夹 添加 gt 新项目 gt 内容页面 我收到此错误 它实际上创建了 xaml
  • 在使用像数组这样的变量之前分配 array()

    我试图找到一个合适的解释性标题 但我找不到 我将尝试解释我在这里问的问题 通常 如果您不将空数组分配给变量 则可以开始为索引分配值 如下所示 hello world Hello World echo hello world 但我总是遇到这样
  • 从工作线程使用 Flask SQLAlchemy

    我有一个 python 应用程序使用烧瓶宁静 http flask restful cn readthedocs io en 0 3 5也Flask SQLAlchemy http flask sqlalchemy pocoo org 2
  • Bootstrap 中缺少可见-** 和隐藏-**

    在Bootstrap v3中我经常使用hidden 类结合clearfix来控制不同屏幕宽度下的多列布局 例如 我可以在一个 DIV 中组合多个 hide 以使我的多列在不同的屏幕宽度下正确显示 举个例子 如果我想显示多行产品照片 在较大的
  • Common Lisp:如何使用条件拼接在宏中构建列表?

    我们假设 defmacro testing optional var list this is when consp var a list 当被调用时 gt testing 2 THIS IS gt testing list 1 2 THI
  • 从 asp.net/C# 查询 MUMPS

    有谁知道如何使用 C 从 MUMPS 数据库查询而不使用 KBSQL ODBC 我们需要从 MUMPS 数据库 Mckesson STAR Patient care 进行查询 当我们使用 KBSQL 时 它仅限于 6 个并发用户 因此我们尝
  • 如何回收/重用 CUDA 线程

    在 CUDA 中 如何为内核中的所有线程创建一个等待的屏障 直到CPU向该障碍发送一个信号 表明继续进行是安全的 有帮助的 我想避免启动 CUDA 内核的开销 有两种类型的开销需要避免 1 在 X 块和 Y 线程上简单启动内核的成本 以及
  • 如何在角度4中以动态形式设置ngIf动态条件

    我正在创建一个动态表单 在其中根据 JSON 的响应动态填充字段 Eg type text required true minlength 3 maxlength 5 name fname visibility true type text
  • 有没有办法使用 HashWithIn DifferentAccess 序列化 ActiveRecord 的 JSON 属性?

    我在用ActiveRecord ConnectionAdapters PostgreSQLAdapter在 Rails 应用程序中 假设我有一个架构 create table foo id bigserial force cascade d
  • 如果未发送,请重试发送邮件

    我正在使用 nodemailer 通过我的节点应用程序发送电子邮件 有时电子邮件不起作用并抛出错误 直到我尝试两次或三次 我希望我的程序一次又一次地尝试 直到邮件成功发送 这是我的代码 const mailOptions from from
  • Django 锁定身份验证 - 登录表单不起作用

    我一直在研究锁定整个页面的方法 一位同事引起了我的注意Django 锁定 https bitbucket org carljm django lockdown src 我已经安装了 我的代码如下所示 INSTALLED APPS lockd
  • jQuery 如何获取元素的边距和填充?

    只是想知道 如何使用 jQuery 我可以获得格式化的总填充和边距等元素 即 30px 30px 30px 30px 或 30px 5px 15px 30px 等 I tried var margT jQuery img css margi
  • StreamingFileSink 未将数据提取到 s3

    我创建了简单的摄取服务 该服务选择本地文件并使用 StreamingFileSink 摄取到 s3 https ci apache org projects flink flink docs stable dev connectors st
  • Java 的快速超越/三角函数

    由于 java lang Math 中的三角函数非常慢 是否有一个库可以快速且良好地近似 似乎可以在不损失太多精度的情况下以数倍的速度进行计算 在我的机器上 乘法需要 1 5ns 而 java lang Math sin 需要 46ns 到
  • 在开始/结束日期将记录拆分为多个记录

    我正在寻找一种解决方案 必须使用另一个表中的数据从一个记录创建一组记录 表定义 DECLARE A AS TABLE AID BIGINT NOT NULL StartDate DATETIME NOT NULL EndDate DATET
  • 如何用SASS将数字转换为百分比? [复制]

    这个问题在这里已经有答案了 我有一张 930 像素 x 530 像素的地图 我想使用 mixin 将纬度 经度坐标转换为框内的顶部 左侧百分比值 这就是我到目前为止所拥有的 mixin latLong lat long left long
  • 使用 PHP 检测日历事件重叠冲突

    我正在开发一项功能 用于检查外部事件是否与内部事件 在日历应用程序中 发生冲突 该过程如下所示 我的应用程序创建了一系列可能的事件 称为 internalEvents 我从 Google Calendar iCloud 等日历 称为 ext