【问题标题】:Return timeslot array based on begin and end time in PHP根据 PHP 中的开始和结束时间返回时隙数组
【发布时间】:2012-12-18 00:28:37
【问题描述】:

以下问题需要您的帮助。我正在使用 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"
    }
  }
}

我一直在为此绞尽脑汁,但想不出一个很好的解决方案来处理跨越多天的开始结束时间。一天的开始和结束时间没有问题:我可以将开始时间与时间段时间进行比较。当然,这在多天之内都行不通。任何指向正确方向的指针都非常感谢!谢谢!

【问题讨论】:

标签: php


【解决方案1】:

另一种算法简单的方法:

<?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);

【讨论】:

    【解决方案2】:

    这是我想出的一个通用函数,它可能会有所帮助。我对“时间段”的计算可能与您想要的不完全匹配,但您可以根据自己的需要进行更新。

    $res = calc('01-12-2012 09:00', '01-12-2012 13:00');
    print_r($res);
    $res = calc('17-12-2012 13:00', '18-12-2012 11:00');
    print_r($res);
    
    function calc($start, $end) {
        // generic way to determine time slot; value is the high hour.
        static $slots = array(1 => 13, 2 => 17, 3 => 23);
    
        $oneDay = new \DateInterval("P1D");
    
        if (!($start instanceof \DateTime)) {
            $start = date_create($start);
        }
        if (!($end instanceof \Datetime)) {
            $end = date_create($end);
        }
    
        $ary = array();
        $now = clone $start;
        do {
            $res = array('day' => $now->format('Y-m-d'));
            foreach ($slots as $idx => $hour) {
                if ($now->format('H') <= $hour) {
                    $res['slot'] = $idx;
                    break;
                }
            }
            $ary[] = $res;
    
            $now->add($oneDay);
        } while ($now->format('Y-m-d') <= $end->format('Y-m-d'));
    
        return $ary;
    }
    

    输出:

    Array
    (
        [0] => Array
            (
                [day] => 2012-12-01
                [slot] => 1
            )
    
    )
    Array
    (
        [0] => Array
            (
                [day] => 2012-12-17
                [slot] => 1
            )
    
        [1] => Array
            (
                [day] => 2012-12-18
                [slot] => 1
            )
    
    )
    

    【讨论】:

      【解决方案3】:

      这似乎测试正常。 http://www.laprbass.com/RAY_temp_daan.php

      <?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);
      

      【讨论】:

        【解决方案4】:

        当您将时间转换为 UNIX TIMESTAMP 时,您可以简单地执行此检查。

        当前时间戳为:1355757162 明天5点的时间戳:1355846439

        应预订大于 1355757162 且小于 1355846439 的每个时间戳。

        【讨论】:

          猜你喜欢
          • 2022-01-24
          • 2012-06-27
          • 1970-01-01
          • 2020-03-21
          • 1970-01-01
          • 1970-01-01
          • 2010-11-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多