我正在努力寻找合并时间的最佳方式......制定用户有两件事的时间表:
X天的可用性和指定时间。
两者的结构相同,看起来像这样:
对于特定日期,请说(2012-10-07)可用性:
[2012-10-07]
[0][start_time] => 08:30
[end_time] => 13:30
[1][start_time] => 16:30
[end_time] => 23:30
现在,对于那一天,他可能会被分配,我的查询结果如下:
[2012-10-07][0][start_time] => 08:30
[end_time] => 09:30
[1][start_time] => 10:30
[end_time] => 11:30
[2][start_time] => 17:00
[end_time] => 18:30
合并的结果应如下所示:
[2012-10-07] [0][start_time]=> 08:30
[start_time]=> 09:30
[assigned]=> true
[1][start_time]=> 09:30
[start_time]=> 10:30
[assigned]=> false
[2][start_time]=> 10:30
[start_time]=> 11:30
[assigned]=> true
[3][start_time]=> 11:30
[start_time]=> 13:30
[assigned]=> false
[4][start_time]=> 16:30
[start_time]=> 17:00
[assigned]=> false
[5][start_time]=> 16:30
[start_time]=> 17:00
[assigned]=> false
[6][start_time]=> 17:00
[start_time]=> 18:30
[assigned]=> true
[7][start_time]=> 18:30
[start_time]=> 23:30
[assigned]=> false
现在,当连接日历时,可用性为绿色(假)并以红色分配(已分配=真)。
我所做的是循环使用可用性,将开始/结束时间转换为UNIX时间戳,然后在每个指定的时间循环并转换为UNIX时间戳。
然后测试所有情况,如果时间在可用性内部或外部,添加临时数组和循环,而不对最终数组进行更改。
(因为每次我生成一个新的时间,我必须在指定的时间再次循环)
它有效,但我不喜欢我这样做的方式......有更好的方法吗?
更新:
对于那些想要在这里看到完整工作代码的人来说:
function removeSessionsFromSchedule($schedule,$remove){
$modified = false;
if(is_array($schedule) && count($schedule) > 0 && is_array($remove) && count($remove) > 1) {
if($modified) {
break;
}
$pos = 0;
$countdispo = count($dispo);
foreach($schedule as $s => $dispo) {
$pos = 0;
$countdispo = count($dispo);
foreach($dispo as $d) {
$abs = $remove[$s];
$counter = 0;
// dispo debut/end
$dis_s = strtotime($d['heure_debut']);
$dis_e = strtotime($d['heure_fin']);
if(is_array($abs) && count($abs) > 0) {
foreach($abs as $a) {
// absence start/end
$abs_s = strtotime($a['heure_debut']);
$abs_e = strtotime($a['heure_fin']);
// (2) [a_s]---[ds - de]---[a_e]
if($abs_s <= $dis_s && $abs_e >= $dis_e) {
// delete availabilities
unset($schedule[$s][$pos]);
$modified = false;
}
// (7)[as == ds] && [ae < de]
else if($abs_s == $dis_s && $abs_e < $dis_e) {
unset($schedule[$s][$pos]);
$schedule[$s][$pos] = $d;
$schedule[$s][$pos]['heure_debut'] = date("H:i",$abs_e);
$schedule[$s][$pos]['heure_fin'] = date("H:i",$dis_e);
$modified = true;
break;
}
// (6) [ds -de] --- [as ae] return dispo as is
else if($abs_s >= $dis_e){
unset($schedule[$s][$pos]);
$schedule[$s][$pos] =$d;
$modified = false;
}
// (5)[as ae] [ds -de] --- return dispo as is
else if($abs_e <= $dis_s){
unset($schedule[$s][$pos]);
$schedule[$s][$pos]= $d;
$modified = false;
}
// (1)[ds] --- [as] --- [ae] --- [de] (duplicate dis with new times)
else if($abs_s > $dis_s && $abs_e <= $dis_e) {
// new times as : // s1 = ds-as && s2 = ae-de
unset($schedule[$s][$pos]);
$schedule[$s][$pos] =$d;
$schedule[$s][$pos+1] =$d;
$schedule[$s][$pos]['heure_debut'] = date("H:i",$dis_s);
$schedule[$s][$pos]['heure_fin'] = date("H:i",$abs_s);
$schedule[$s][$pos + 1]['heure_debut'] = date("H:i",$abs_e);
$schedule[$s][$pos + 1]['heure_fin'] = date("H:i",$dis_e);
//$pos++;
$modified = true;
break;
}
// (3)[as] -- [ds] --- [ae] -- [de]
else if($abs_s < $dis_s && $abs_e < $dis_e) {
unset($schedule[$s][$pos]);
$schedule[$s][$pos] =$d;
$schedule[$s][$pos]['heure_debut'] = date("H:i",$abs_e);
$schedule[$s][$pos]['heure_fin'] = date("H:i",$dis_e);
$modified = true;
break;
}
// (4) [ds]---[as]--- [de]--- [ae]
else if($abs_s > $dis_s && $abs_s < $dis_e && $abs_e > $dis_e) {
unset($schedule[$s][$pos]);
$schedule[$s][$pos] =$d;
$schedule[$s][$pos]['heure_debut'] = date("H:i",$dis_s);
$schedule[$s][$pos]['heure_fin'] = date("H:i",$abs_s);
$modified = true;
break;
}
else {$modified = false ;}
}
} else {$modified =false;}
$pos++;
}
}
}
else {$modified = false;}
if($modified) {
$schedule = removeSessionsFromSchedule($schedule,$remove);
}
return $schedule;
}
合并时间的函数:
function mergeSessionFromSchedule($schedule ,$seances) {
$sessions = removeSessionsFromSchedule($schedule,$seances);
$mergedSessions = array_merge_recursive($sessions , $seances);
foreach($mergedSessions as $s => $val) {
$sortedSessions[$s] = subval_sort_by_time($val,'heure_debut');
}
return $sortedSessions ;
}
助手:
function subval_sort_by_time($a,$subkey) {
foreach($a as $k=>$v) {
$b[$k] = strtotime($v[$subkey]);
}
asort($b);
foreach($b as $key=>$val) {
$c[] = $a[$key];
}
return $c;
}
答案 0 :(得分:1)
这是我的解决方案:
<?php
class SessionHandler {
private $keys = array();
private $times = array();
private $slots = array();
private $merged = array();
function __construct($available, $assigned) {
$this->times = array(
'available' => $available,
'assigned' => $assigned
);
$this->slots = array(
'available' => array(),
'assigned' => array(),
'excluded' => array()
);
$this->getKeys($this->times['available']);
$this->loadSessions($this->keys[0], $this->keys[1]);
}
private function getKeys($arr) {
if (count($arr)) {
$this->keys = array_keys($arr[0]);
} else {
throw new Exception('Invalid array format');
}
}
private function loadSessions($start, $end) {
foreach ($this->times as $type => $periods) {
foreach ($periods as $hours) {
$this->slots[$type][] = $hours[$start].'-'.$hours[$end];
$this->merged[] = strtotime($hours[$start]);
$this->merged[] = strtotime($hours[$end]);
}
}
$this->merged = array_unique($this->merged);
sort($this->merged);
$hours = $this->times['available'];
for ($i = 0; $i < count($hours) - 1; $i++) {
$this->slots['excluded'][] = $hours[$i][$end].'-'.$hours[$i + 1][$start];
}
}
public function mergeSessions() {
$result = array();
for ($i = 0; $i < count($this->merged) - 1; $i++) {
$start_hour = date('H:i', $this->merged[$i]);
$end_hour = date('H:i', $this->merged[$i + 1]);
$slot = $start_hour . '-' . $end_hour;
if (!in_array($slot, $this->slots['excluded'])) {
$assigned = in_array($slot, $this->slots['assigned']);
$result[] = array(
$this->keys[0] => $start_hour,
$this->keys[1] => $end_hour,
'assigned' => $assigned ? "true" : "false"
);
}
}
return($result);
}
}
$availability = array(
'2012-10-07' => array(
array('start_time' => '08:30', 'end_time' => '13:30'),
array('start_time' => '16:30', 'end_time' => '23:30')
)
);
$assignments = array(
'2012-10-07' => array(
array('start_time' => '08:30', 'end_time' => '09:30'),
array('start_time' => '10:30', 'end_time' => '11:30'),
array('start_time' => '17:00', 'end_time' => '18:30')
)
);
$sessions = array();
foreach ($availability as $day => $available) {
$assigned = isset($assignments[$day]) ? $assignments[$day] : array();
$SH = new SessionHandler($available, $assigned);
$sessions[$day] = $SH->mergeSessions();
}
?>
<!DOCTYPE html>
<html>
<body>
<pre><?php print_r($sessions) ?></pre>
</body>
</html>