I am stumped about how to go about checking to see if multiple *date/time value -ranges- (meaning: start and end times) are in conflict with one another.
Summary & samples of data I need to work with.
I have an (app) events table, that is used to create a form for the user to go through and check off (checkboxes) all the sessions/events they attended.
The names of the checkboxes are generated using info about the session. (month/day start/end times along with a session id)
ie: hours_9_5_p02_800_845
9 = month
5 = date
p02 = session id/event code
800 = start time
845 = end time
all delimited by an underscore ("_")
If the user checks (and submits) multiple sessions, there will be many of these values to check for a time conflict..
hours_9_5_p08_755_800
hours_9_5_p02_800_845
hours_9_5_p02_800_855
hours_9_5_p03_800_845
hours_9_5_p04_820_835
hours_9_5_p04_845_900
hours_9_5_REG_900_915
hours_9_5_REG_1300_1305
hours_9_5_REG_1310_1335
hours_9_5_REG_1320_1335
The above is an example of the fieldlist/array that I 'could' get as a user selection/submission that I need to check for any possible conflicts (obviously the user couldnt be two places at once) :) And the above have many/several overlapping of just the same exact time slots selected.
** I am open to either PHP, (checking after the user submits) or javascript/jQuery (if it can do the date/time RANGE conflict checking, it might be easier to then highlight those rows/elements on the page if done on the front end)
I'd image, first you need to parse those checkbox names/strings from the fieldlist array...
which I have done like so: (php)
function conflictParse($delimiter, $targetString){
//echo 'fired';
$breakDown = explode($delimiter, $targetString);
$startTime = substr_replace($breakDown[4] , ':', -2, 0);
$endTime = substr_replace($breakDown[5] , ':', -2, 0);
$startString = "$breakDown[1]/$breakDown[2]/2015 $startTime";
$endString = "$breakDown[1]/$breakDown[2]/2015 $endTime";
$startFormat = strtotime($startString);
$endFormat = strtotime($endString);
$start = date('m/d/Y G:i',$startFormat);
$end = date('m/d/Y G:i',$endFormat);
return "Session Times: $start -- $end <br>";
}
echo conflictParse('_','hours_9_5_p02_800_845');
but I am not clear on HOW to go about using this RANGE of a date start & end time to check against MULTIPLE other date start/end time RANGES?
maybe just sticking with having PHP parse/check conflict upon submit and then return some array of the (original) names page to the page (for some jQuery to use and highlight the elements..etc (but I can handle that aspect later.. for right now I am need help on how I can get the above parse 'date/time' start/end range values checked for conflicts against other 'date/time' start/end range values
update:
Here is the current nested associative array I have to work with for comparing:
Array (
[0] => Array (
[id] => hours_9_9_p02_800_845
[fullStart] => 09/09/2015 8:00
[fullEnd] => 09/09/2015 8:45
[month] => 9
[date] => 9
[session_code] => p02
[start] => 8:00
[end] => 8:45
[hasConflict] => false
)
[1] => Array (
[id] => hours_9_9_p02_800_855
[fullStart] => 09/09/2015 8:00
[fullEnd] => 09/09/2015 8:55
[month] => 9
[date] => 9
[session_code] => p02
[start] => 8:00
[end] => 8:55
[hasConflict] => false
)
[2] => Array (
[id] => hours_9_9_p03_800_845
[fullStart] => 09/09/2015 8:00
[fullEnd] => 09/09/2015 8:45
[month] => 9
[date] => 9
[session_code] => p03
[start] => 8:00
[end] => 8:45
[hasConflict] => false
)
[3] => Array (
[id] => hours_9_9_p04_820_830
[fullStart] => 09/09/2015 8:20
[fullEnd] => 09/09/2015 8:30
[month] => 9
[date] => 9
[session_code] => p04
[start] => 8:20
[end] => 8:30
[hasConflict] => false
)
[4] => Array (
[id] => hours_9_9_p04_845_900
[fullStart] => 09/09/2015 8:45
[fullEnd] => 09/09/2015 9:00
[month] => 9
[date] => 9
[session_code] => p04
[start] => 8:45
[end] => 9:00
[hasConflict] => false
)
[5] => Array (
[id] => hours_9_9_REG_1300_1315
[fullStart] => 09/09/2015 13:00
[fullEnd] => 09/09/2015 13:15
[month] => 9
[date] => 9
[session_code] => REG
[start] => 13:00
[end] => 13:15
[hasConflict] => false
)
[6] => Array (
[id] => hours_9_9_REG_1300_1330
[fullStart] => 09/09/2015 13:00
[fullEnd] => 09/09/2015 13:30
[month] => 9
[date] => 9
[session_code] => REG
[start] => 13:00
[end] => 13:30
[hasConflict] => false
)
)
I need to convert your js functions over to PHP and of course use the fullStart/fullEnd variables in my time compares I guess..??
(but your function is still confusing me as I see references to event1, event 2.. (to match your example)..
update 2:
The above is my object/array (associative array) that I got from selecting some check boxes, and submitting my form...
Here is my attempt to convert your JS code to PHP based [with some update variablenames]: (and the commented out lines just to try and get some sort of output somewhere)
print_r($conflict_list);
function checkFirst($cf_presX, $cf_presY) {
//$cf_presX['fullStart'] < $cf_presY['fallStart'] ? checkConflict($cf_presX, $cf_presY) : checkConflict($cf_presY, $cf_presX);
echo 'Pres Check: '.$cf_presX[0] . '<br>';
echo 'Pres Check: '.$cf_presY[0] . '<br>';
/*
function checkConflict ($cc_presX, $cc_presY) {
if ($cc_presX.['fullEnd'] > $cc_presY.['fullStart']) {
$cc_presX.['hasConflict'] = true;
$cc_presY.['hasConflict'] = true;
}
}
*/
}
function setConflicts($events) {
for ($i = 0; $i < count($events); $i++) {
for ($j = 0; $i < count($events); $j++) {
// if it is not the same event
// if (i !== j) is the same $age['Peter']
if ($events[$i]['id'] !== $events[$j]['id']) {
checkFirst($events[$i], $events[$j]);
}
}
}
}
setConflicts($conflict_list);
I just keep getting a loop with undefined offset: (counting up to the 100k+ mark)
Notice: Undefined offset: 0 in C:\wamp\www\projects\misc\conflict_check_new.php on line 49 Pres Check:
Notice: Undefined offset: 0 in C:\wamp\www\projects\misc\conflict_check_new.php on line 50 Pres Check:
Notice: Undefined offset: 0 in C:\wamp\www\projects\misc\conflict_check_new.php on line 49 Pres Check:
The same logic could apply in PHP, but assuming you can get your events out into JavaScript and create an array of objects with start and end dates like so:
var events = [
{
id: 'event1',
start: new Date('1/1/1 5:00'),
end: new Date('1/1/1 6:00'),
hasConflict: false
},
{
id: 'event2',
start: new Date('1/1/1 5:30'),
end: new Date('1/1/1 6:30'),
hasConflict: false
},
{
id: 'event3',
start: new Date('1/1/1 7:30'),
end: new Date('1/1/1 8:30'),
hasConflict: false
}
]
You can compare events to see if the one that starts first, has an end time that's later the second one's start time.
function checkFirst (event1, event2) {
event1.start < event2.start
? checkConflict(event1, event2)
: checkConflict(event2, event1)
function checkConflict (first, second) {
if (first.end > second.start) {
first.hasConflict = second.hasConflict = true
}
}
}
Then you can check events against each other. Here's a not particularly efficient, but at least suitable loop:
function flagAllEventsWithConflicts (events) {
events.forEach(event1 => {
events.forEach(event2 => {
event1.id !== event2.id && checkFirst(event1, event2)
})
})
}
Update: The above function can also be written as a nested for loop:
function flagAllEventsWithConflicts (events) {
for (var i = 0; i < events.length; i++) {
for (var j = 0; j < events.length; j++ {
// if it is not the same event
// if (i !== j) is the same
if (events[i].id !== events[j].id) {
checkFirst(events[i], events[j])
}
}
}
}
Then check to see if hasConflict
is true or false:
flagAllEventsWithConflicts(events)
console.table(events)