我有一个阵列,是由那些想要预留时间段来为我们的组织做志愿者的人制作的。我想检查他们是否在重叠的同一天选择了时间块。在我的示例数组中,第一个和第三个元素重叠,我需要检测它。任何建议都将非常感谢:
Array
(
[0] => Array
(
[id_pc_time_blocks] => 3
[id_pc] => 2
[pc_date] => 2012-11-21
[pc_time_block] => 9:00 AM-1:00 PM
[pc_time_block_max] => 25
[pc_time_block_count] => 0
[pc_name] => Atlanta
)
[1] => Array
(
[id_pc_time_blocks] => 4
[id_pc] => 2
[pc_date] => 2012-11-21
[pc_time_block] => 1:00 PM-5:00 PM
[pc_time_block_max] => 25
[pc_time_block_count] => 10
[pc_name] => Atlanta
)
[2] => Array
(
[id_pc_time_blocks] => 6
[id_pc] => 2
[pc_date] => 2012-11-21
[pc_time_block] => 10:00 AM-2:00 PM
[pc_time_block_max] => 25
[pc_time_block_count] => 0
[pc_name] => Atlanta
)
[3] => Array
(
[id_pc_time_blocks] => 6
[id_pc] => 2
[pc_date] => 2012-11-23
[pc_time_block] => 10:00 AM-2:00 PM
[pc_time_block_max] => 25
[pc_time_block_count] => 0
[pc_name] => Atlanta
)
[4] => Array
(
[id_pc_time_blocks] => 6
[id_pc] => 2
[pc_date] => 2012-11-23
[pc_time_block] => 3:00 AM-6:00 PM
[pc_time_block_max] => 25
[pc_time_block_count] => 0
[pc_name] => Atlanta
)
)
答案 0 :(得分:1)
不建议用于HUGE阵列,但这是一个快速的解决方案。你需要将unte时间分解为comparisson的unix时间戳
// Run down each element of the array. (I've called it MyStartArray)
$numElements = count($MyStartArray);
for ($i=0; $i<$numElements ; $i++) {
// Calculate "Start Time" and "End Time" as Unix time stamps (use mktime function) and store as another items in the array
// You can use preg_match or substr to get the values to pump into mktime() below - not writing hte whole thing for you ;)
$MyStartArray[$i]['start_time'] = mktime( ... );
$MyStartArray[$i]['end_time'] = mktime( ... );
// Now run through all the previous elements to see if a start time is before the end time, or an end time is after the start time.
if ($i > 0) {
for ($j=0; $j<$i;$j++) {
if ($MyStartArray[$i]['start_time'] < $MyStartArray[$j]['end_time'] ||
$MyStartArray[$j]['end_time'] > $MyStartArray[$j]['start_time'] ) {
echo 'CLASH';
}
}
}
}
答案 1 :(得分:0)
以下是我检查重叠时间的每个日期的解决方案。唯一的问题是,这是针对我的特定情况,并不考虑重叠年份,因为我对此应用程序没有这种需求。
以下是我的工作示例:
$dateIdx = 0;
foreach($timeblocks_array as $obj) {
$timeblocks_array[$dateIdx]["intDay"] = idate("z",strtotime($obj["pc_date"]));
$timeblocks_array[$dateIdx]["intStart"] = intval($obj["start_time"]);
$timeblocks_array[$dateIdx]["intEnd"] = intval($obj["end_time"]);
$mindates[] = idate("z",strtotime($obj["pc_date"]));
$dateIdx++;
}
$minDateSingle = min($mindates);
$maxDateSingle = max($mindates);
$currentDate = $minDateSingle;
$dateIdx = 0;
while ($currentDate <= $maxDateSingle) {
$hrIndex = 0;
while ($hrIndex < 24) {
$matrixArray[$dateIdx][$hrIndex]["count"] = 0;
$matrixArray[$dateIdx][$hrIndex]["intDay"] = $currentDate;
$hrIndex++;
}
// calculate counts:
$hourIdx = 0;
foreach($matrixArray[$dateIdx] as $hour){
foreach($timeblocks_array as $block) {
if ($hour["intDay"] == $block["intDay"]) {
if ($hourIdx >= $block["intStart"] && $hourIdx < $block["intEnd"]) {
$matrixArray[$dateIdx][$hourIdx]["count"] = $matrixArray[$dateIdx][$hourIdx]["count"] + 1;
$matrixArray[$dateIdx][$hourIdx]["requests"][] = $block;
}
}
}
$hourIdx++;
}
$dateIdx++;
$currentDate = $currentDate + 1;
}
//loop through the matrix array and timeblocks array to see if they intersect
foreach($matrixArray as $day) {
$hourIdx = 0;
foreach($day as $hour) {
if ($hour["count"] > 1) {
//echo $hour["intDay"]." - Overlap on Hour $hourIdx\n";
$smarty->assign('overlappingError', 1);
$error = 1;
foreach($hour["requests"] as $overlapblock) {
//echo " --> conflict: ". $overlapblock["pc_date"]." ".$overlapblock["pc_time_block"]." (".$overlapblock["intStart"]." to ".$overlapblock["intEnd"].")\n";
}
} else if ($hour["count"] == 1) {
// these are valid hours
}
$hourIdx++;
}
}
答案 2 :(得分:0)
罗比的回答对我不起作用。我发现需要制定的规则仅仅是关于日期的例子:
$ i [start]需要小于且不等于$ i [stop]
$ i [start]需要大于且不等于$ j [stop]
$ j [start]需要小于且不等于$ j [stop]
因此我的解决方案是:
$numElements = count($dates);
for ($i=0; $i<$numElements; $i++) {
$dates[$i]['start_time'] = strtotime($dates[$i]['start']);
$dates[$i]['end_time'] = strtotime($dates[$i]['end']);
if ($i > 0) {
for ($j=0; $j<$i;$j++) {
if($dates[$i]['start_time'] >= $dates[$i]['end_time'] || $dates[$i]['start_time'] <= $dates[$j]['end_time'] || $dates[$j]['start_time'] >= $dates[$j]['end_time']) {
$this->set_error(['dates_overlap']);
$this->dates_overlap = true;
break;
}
}
}
if(isset($this->dates_overlap))
break;
}