此脚本判断60分钟的时段是否在某个时间范围内可用,同时考虑到已预订的时段. 它适用于第一个已预订的空位,但不考虑第二个空位.此外,如果我将第一个预订的时段更改为12:10,它也不会检测到它.

基本上,我们的 idea 是,如果在射程和已经预订的时段之间有60分钟的时段来展示它.

For example,,如果我们的范围是9:0015:00,并且我们从11:1014:00有两个预订的时隙,则返回9:00, 10:00 and 12:10中的可用时隙

$start_time = '2022-10-21 09:00:00';  //start time as string
$end_time = '2022-10-21 15:00:00';  //end time as string
$booked = ['2022-10-21 12:00:00','2022-10-21 13:00:00']; //booked slots as arrays
$start = DateTime::createFromFormat('Y-m-d H:i:s',$start_time); //create date time objects
$end = DateTime::createFromFormat('Y-m-d H:i:s',$end_time);  //create date time objects
$time1 = $start;
$count = 0;  //number of slots
$out = array();   //array of slots 
for($i = $start; $i<$end;)  //for loop 
{
    $avoid = false; 
    $t1 = date_timestamp_get($i);
    $t2 = $t1+(60*60);

    for($k=0;$k<sizeof($booked);$k+=2)  //if booked hour
    {
        $st = DateTime::createFromFormat('Y-m-d H:i:s',$booked[$k]);
        $en = DateTime::createFromFormat('Y-m-d H:i:s',$booked[$k+1]);
          
        if( $t1 >= date_timestamp_get($st) && $t2 <= date_timestamp_get($en)  )
        $avoid = true;   //yes. booked
    }
    $slots =[ $i->format('H:i'),$i->modify("+60 minutes")->format('H:i')];
    if(!$avoid && $i<$end)  //if not booked and less than end time
    {
        $count++;  
        array_push($out,$slots);  //add slot to array
    }
}
var_dump($out);   //array out

Here is link to sandbox. https://onlinephp.io/c/b0b77.

Additional information

假设我们有一个从10:00 until 13:00开始的空闲时间框架.如果时间段是60 min,则脚本应返回10:0011:0012:00作为可能性.

如果时隙是45 min.例如,它应该返回10:0010:4511:3012:15.

因此,可能的变型应该从随着时隙(45, 60, or whatever time slot is set)增加的第一个可能选项开始

插槽不能从10:12, 10:44, or another custom time开始

The Solutions

下面的Salman AJim两个解决方案都像预期的那样工作.只是使用一点不同的方法.

推荐答案

如果对预订日期进行排序,则可以使用简单的嵌套循环来完成此操作.请注意数据中的模式;从一行开始的结束日期和从下一行开始的日期组成一个available范围,您可以在其中创建槽:

$start_time =                                        '2022-10-21 09:00:00';
$booked = array(
    array('start' => '2022-10-21 11:10:00', 'end' => '2022-10-21 12:10:00'),
    array('start' => '2022-10-21 14:00:00', 'end' => '2022-10-21 15:00:00')
);
$end_time =          '2022-10-21 15:00:00';
$slot_size = 60;
// data must be sorted by date
usort($booked, function($a, $b) {
    return DateTime::createFromFormat('Y-m-d H:i:s', $a['start']) <=> DateTime::createFromFormat('Y-m-d H:i:s', $b['start']);
});
$interval = new DateInterval('PT' . $slot_size . 'M');
$result = array();
for ($i = 0, $j = count($booked); $i <= $j; $i++) {
    // loop count + 1 times
    // first and last iterations are special
    $range_start = $i === 0 ? DateTime::createFromFormat('Y-m-d H:i:s', $start_time) : DateTime::createFromFormat('Y-m-d H:i:s', $booked[$i - 1]['end']);
    $range_end = $i < $j ? DateTime::createFromFormat('Y-m-d H:i:s', $booked[$i]['start']) : DateTime::createFromFormat('Y-m-d H:i:s', $end_time);
    $t1 = (clone $range_start);
    $t2 = (clone $range_start)->add($interval);
    while ($t2 <= $range_end) {
        $result[] = array('start' => $t1->format('Y-m-d H:i:s'), 'end' => $t2->format('Y-m-d H:i:s'));
        $t1->add($interval);
        $t2->add($interval);
    }
}
var_dump($result);

Php相关问答推荐

输入手写CSV时在PHP中进行日期判断

PHP FFI—将PHP数组转换为C指针数组

根据用户组或登录状态显示或隐藏定价后添加的文本

保存PHP条带以备将来使用,不显示用户界面

WooCommerce:在 checkout 审核单和发票中显示定制产品数据

如何将WooCommerce产品属性术语名称显示为链接术语?

在PHP中读取JSON

PHP从响应应用程序json获取文件代码和URL

如何在汇总表构建器中操作LALAVEL细丝Sum::Make()值

基于服务器的不同地平线配置

向WooCommerce管理订单总额添加自定义总额行

如何用十进制和字母数字减go 和添加 id

如何在 PHP 中对具有相同数组值的值求和

避免在 WooCommerce 中多次触发挂钩函数

PHP preg_replace括号和方括号内的所有逗号

为什么 AJAX 请求没有通过 is_ajax_request() codeigniter 的条件?

Laravel 10 单元测试看不到来自 Artisan Command 的数据库更改

在 WooCommerce 结帐后更新用户元字段

mysql / sql修复多对多数据库中的行

用于多态服务的 Symfony setter 注入