在PHP中返回基于开始和结束时间的时隙数组

在PHP中返回基于开始和结束时间的时隙数组,php,Php,我需要你在以下问题上的帮助。我正在使用PHP构建一个网站,我想在上面显示一个日历,显示一周中的几天,每天细分为3个时间段。这些时隙要么是免费的,要么是预定的,在这种情况下,该时隙是不可选择的 到目前为止还不错,但问题在于显示已预订的时间段。我从一个脚本中获取预订数据,该脚本给出了开始日期和时间,以及结束日期和时间。这些日期/时间戳可以是任何东西,并且不绑定到时隙时间。它们可以在同一天,也可以跨越多天。每天的时间段相同:9到13小时、13到17小时和19到23小时 例如,假设我的开始时间为17-1

我需要你在以下问题上的帮助。我正在使用PHP构建一个网站,我想在上面显示一个日历,显示一周中的几天,每天细分为3个时间段。这些时隙要么是免费的,要么是预定的,在这种情况下,该时隙是不可选择的

到目前为止还不错,但问题在于显示已预订的时间段。我从一个脚本中获取预订数据,该脚本给出了开始日期和时间,以及结束日期和时间。这些日期/时间戳可以是任何东西,并且不绑定到时隙时间。它们可以在同一天,也可以跨越多天。每天的时间段相同:9到13小时、13到17小时和19到23小时

例如,假设我的开始时间为17-12-2012 13:00,结束时间为18-12-2012 11:00,我希望我的函数为我提供如下数组:

array(1) {
  ["meetingroom1_booked"]=>
  array(3) {
    [0]=>
    array(2) {
      ["day"]=>
      string(10) "2012-12-17"
      ["timeslot"]=>
      string(1) "2"
    }
    [1]=>
    array(2) {
      ["day"]=>
      string(10) "2012-12-17"
      ["timeslot"]=>
      string(1) "3"
    }
    [2]=>
    array(2) {
      ["day"]=>
      string(10) "2012-12-18"
      ["timeslot"]=>
      string(1) "1"
    }
  }
}

我一直在为此绞尽脑汁,但却找不到一个好的解决方案来处理跨越数天的开始-结束时间。由于开始和结束时间都在一天内,所以没有问题:我可以将开始和结束时间与时隙时间进行比较。当然,这在几天内都不起作用。任何指向正确方向的指针都将受到高度赞赏!谢谢

将时间转换为UNIX时间戳时,只需执行此检查即可

当前时间戳为:1355757162 时间戳tommorow 5点钟:1355846439


每个大于1355757162小于1355846439的时间戳都应该被预订。

这里有一个我想到的通用函数,可能会有所帮助。我对“时间间隔”的计算可能不完全符合您的要求,但您可能会根据您的需要对其进行更新

$res=calc('01-12-2012 09:00','01-12-2012 13:00');
印刷品(港币);;
$res=calc('17-12-2012 13:00','18-12-2012 11:00');
印刷品(港币);;
函数计算($start,$end){
//确定时隙的一般方法;值为高峰小时。
静态$slots=array(1=>13,2=>17,3=>23);
$oneDay=new\DateInterval(“P1D”);
如果(!($start instanceof\DateTime)){
$start=创建日期($start);
}
如果(!($end instanceof\Datetime)){
$end=创建日期($end);
}
$ary=array();
$now=克隆$start;
做{
$res=array('day'=>$now->format('Y-m-d');
foreach($idx=>$hour){
如果($now->format('H'),则添加($oneDay);
}而($now->format('Y-m-d')format('Y-m-d');
返回$ary;
}
输出:

数组
(
[0]=>阵列
(
[日期]=>2012-12-01
[插槽]=>1
)
)
排列
(
[0]=>阵列
(
[日期]=>2012-12-17
[插槽]=>1
)
[1] =>阵列
(
[日期]=>2012-12-18
[插槽]=>1
)
)

这似乎测试正常


另一种算法简单的方法:


在我查看您的数据时,请看一下本文。感谢大家的帮助,修复了它!
<?php // RAY_temp_daan.php
error_reporting(E_ALL);

/* PROBLEM DEFINITION
The timeslots are the same for each day: from 9 to 13, 13 to 17, and 19 to 23 hrs.

For example, say I have a start time of 17-12-2012 13:00, and an end time of 18-12-2012 11:00, I want my function to give me an array like this:

array(1) {
  ["meetingroom1_booked"]=>
  array(3) {
    [0]=>
    array(2) {
      ["day"]=>
      string(10) "2012-12-17"
      ["timeslot"]=>
      string(1) "2"
    }
    [1]=>
    array(2) {
      ["day"]=>
      string(10) "2012-12-17"
      ["timeslot"]=>
      string(1) "3"
    }
    [2]=>
    array(2) {
      ["day"]=>
      string(10) "2012-12-18"
      ["timeslot"]=>
      string(1) "1"
    }
  }
}
*/

// THE TIMEZONE
date_default_timezone_set('America/Chicago');

// THE START AND END TIMES
$alpha = '2012-12-17 13:00';
$omega = '2012-12-18 11:00';

// THE DEFINITION OF THE TIMESLOTS
$slots = array
( 1 => array
       ( 'lo' => '0900'
       , 'hi' => '1259'
       )
, 2 => array
       ( 'lo' => '1300'
       , 'hi' => '1659'
       )
, 3 => array
       ( 'lo' => '1900'
       , 'hi' => '2259'
       )
)
;

// MAKE AN ARRAY OF TIMESTAMPS OF THE HOURS
$tsa = strtotime($alpha);
$tsz = strtotime($omega);
$hours = range($tsa, $tsz, 3600);

// ASSIGN EACH HOUR TO A SLOT
foreach ($hours as $hour)
{
    $hhmm = date('Hi', $hour);
    foreach ($slots as $slot => $times)
    {
        if ($hhmm >= $times['lo'])
        {
            if ($hhmm <= $times['hi'])
            {
                // USE STRING NOTATION HERE SO WE CAN USE ARRAY_UNIQUE()
                $taken[$hour] = date('Y-m-d', $hour) . '|' . $slot;
            }
        }
    }
}
// REMOVE THE REDUNDANCIES
$taken = array_unique($taken);

// CONSTRUCT THE ASSOCIATIVE ARRAYS
foreach($taken as $thing)
{
    $arr = explode('|', $thing);
    $out[] = array('day' => $arr[0], 'timeslot' => $arr[1]);
}
// CONSTRUCT THE FINAL ARRAY
$out = array("meetingroom1_booked" => $out);

// SHOW THE WORK PRODUCT
echo '<pre>';
var_dump($out);
<?php
$start_date = '2012-12-17';
$start_time = '13:00';
$end_date = '2012-12-18';
$end_time = '11:00';
$slots = array(1=>'09:00', 2=>'13:00', 3=>'19:00');

// [helper]
$start_date_stamp = strtotime($start_date);
$end_date_stamp = strtotime($end_date);
$startdate_timestamp = strtotime($start_date . ' ' . $start_time);
$enddate_timestamp = strtotime($end_date . ' ' . $end_time);
// [/helper]

$cur_date_stamp = $start_date_stamp;
$result = array();
if ($enddate_timestamp >= $startdate_timestamp) {
    // [loop for each date]
    while($cur_date_stamp <= $end_date_stamp) {
        foreach($slots as $slkey=>$slval) {
            if ($cur_date_stamp == $start_date_stamp) { // compare for current date = start date
                $check_slot_stamp = strtotime(date('Y-m-d', $cur_date_stamp) . ' ' . $slval);
                if ($startdate_timestamp <= $check_slot_stamp) {
                    $result[] = array(
                        'day' => date('Y-m-d', $cur_date_stamp),
                        'timeslot' => $slkey
                    );
                }
            }
            elseif ($cur_date_stamp == $end_date_stamp) { // compare for current date = end date
                $check_slot_stamp = strtotime(date('Y-m-d', $cur_date_stamp) . ' ' . $slval);
                if ($check_slot_stamp <= $enddate_timestamp) {
                    $result[] = array(
                        'day' => date('Y-m-d', $cur_date_stamp),
                        'timeslot' => $slkey
                    );
                }
            }
            else { // 3 slots will be added for any date other than start_date and end_date
                $result[] = array(
                    'day' => date('Y-m-d', $cur_date_stamp),
                    'timeslot' => $slkey
                );
            }
        }
        $cur_date_stamp = strtotime('+1 day', $cur_date_stamp); // next day
    }
    // [/loop for each date]
}
$result = array('meetingroom1_booked'=>$result);
var_dump($result);