使用PHP Codeigniter和Mysql过滤免费日间时段

问题描述 投票:-1回答:1

请帮忙 !!!我想要以与“搜索”按钮相关联的表格格式在新结果页面上的自由日期时间段(数据),以便在单击搜索按钮后输出详细信息。 Result Image

我知道所需时段的长度(例如1小时) - Image

可用时隙不能重叠。

怎么能实现这一目标?您认为最好的方法是什么?

流程步骤

  1. https://i.stack.imgur.com/FrP09.png
  2. After Hit Seach Button

我的数据库结构

Event_ID | dt_start          | dt_end            
+----------+---------------------+---------------------+
|        3 | 2013-09-21 16:00:00 | 2013-09-21 16:30:00 |
|       21 | 2013-09-21 09:00:00 | 2013-09-21 09:15:00 |
|        5 | 2013-09-21 09:15:00 | 2013-09-21 10:15:00 | 
|       64 | 2013-09-21 15:00:00 | 2013-09-21 15:45:00 |     
|       32 | 2013-09-21 10:15:00 | 2013-09-21 11:30:00 | 
|        6 | 2013-09-21 13:00:00 | 2013-09-21 14:45:00 |  
+----------+---------------------+---------------------+

已经感谢你的帮助,

php mysql codeigniter-3
1个回答
0
投票

这个答案是基于herehere的想法。

算法的想法如下:

  1. 我们创建一个数组,其中索引是日期的所有可能分钟,值为true
  2. 我们将现有活动中包含的所有会议记录填写到false
  3. 最后,我们寻找大小为$length的连续时间间隔(以分钟为单位),一旦我们可以遍历数组而没有找到false迭代的$length值,我们发现了一个新事件的空时隙。
<?php
require("database.php");

// Create an array with all the timeslots (in minutes) of a date
// Example: $date = '2018-03-21'
//          $timeslots['2018-03-21 00:00:00'] = true;
//          $timeslots['2018-03-21 00:01:00'] = true;
//          $timeslots['2018-03-21 00:02:00'] = true;
//                            until
//          $timeslots['2018-03-21 23:59:00'] = true;
function getAllTimeslots($date)
{
    $currentDate = strtotime($date . " 00:00:00");
    $endDate = strtotime($date . " 23:59:59");

    $timeslots = [];
    while ($currentDate <= $endDate) {
        $index = date("Y-m-d H:i:s", $currentDate);
        $timeslots[$index] = true;
        $currentDate = strtotime("+1 minute", $currentDate);
    }
    return $timeslots;
}


// Based on the events table registers, fill the intervals of the timeslots array marking them as false, i.e., not available
// Therefore, it will result on an array with trues and falses marking if the specific minute is already filled by an event
function fillUsedTimeslots($date, $timeslots)
{
    $queryDate = $date . "%";
    $conn = openConnection();
    $result = $conn->query("SELECT dt_start, dt_end
                            FROM events
                            WHERE dt_start LIKE '" . mysqli_real_escape_string($conn, $queryDate) . "'
                                OR dt_end LIKE '" . mysqli_real_escape_string($conn, $queryDate) . "'");

    if ($result->num_rows > 0) {
        while ($row = $result->fetch_assoc()) {
            $start = strtotime($row['dt_start']);
            $end = strtotime($row['dt_end']);

            // update the timeslots data structure with the information of the events' time usage
            while ($start < $end) {
                $currentDatetime = date("Y-m-d H:i:s", $start);
                $timeslots[$currentDatetime] = false;
                $start = strtotime("+1 minute", $start);
            }
        }
    }

    return $timeslots;
}

// Finally, we need to find a free an interval of time ($length) where we can place an event
// In short words, it iterates over the array of $timeslots looking for $length consecutives trues, i.e.,
// if $length=60, we iterate over the array looking for 60 times of consecutives falses
function findFreeTimeslots($date, $length, $timeslots)
{
    $currentDate = strtotime($date . " 00:00:00");
    $endDate = strtotime($date . " 23:59:00");

    $timeInterval = 0;
    while ($currentDate <= $endDate) {
        $index = date("Y-m-d H:i:s", $currentDate);

        if ($timeslots[$index]) { // Timeslot is free for use
            $timeInterval += 1;
        } else { // Reset timeInterval
            $timeInterval = 0;
        }

        // We have $length consecutives true, i.e., an interval of $length minutes available for another event
        if ($timeInterval == $length + 1) {
            echo "<br/>Timeslot found: " . date("Y-m-d H:i:s", strtotime("-" . $length . " minutes", $currentDate)) . " - " . $index;
            $timeInterval = 1;
        }
        $currentDate = strtotime("+1 minute", $currentDate);
    }
}

// Main
$timeslots = getAllTimeslots("2013-09-21");
$filledTimeslots = fillUsedTimeslots("2013-09-21", $timeslots);
findFreeTimeslots("2013-09-21", 180, $filledTimeslots);

我应用了你的3小时间隔的例子,结果是:

Timeslot found: 2013-09-21 00:00:00 - 2013-09-21 03:00:00
Timeslot found: 2013-09-21 03:00:00 - 2013-09-21 06:00:00
Timeslot found: 2013-09-21 16:30:00 - 2013-09-21 19:30:00
Timeslot found: 2013-09-21 19:30:00 - 2013-09-21 22:30:00

您可以将时隙数据结构大小限制为仅工作时间,或者将不同的条件限制为适应您的项目。而且,重构它,自从我编写vanilla PHP以来已经有很长一段时间了

© www.soinside.com 2019 - 2024. All rights reserved.