KFE KFE - 3 months ago 14
Javascript Question

Finding the next available timeslot in an array of data

I have an array with an 'events' array inside of it that contains an array of events.

$data = array(
'events'=> array(
array(
'title' => 't1',
'start_time' => '12:00AM',
'end_time' => '1:00AM',
),
array(
'title' => 't1',
'start_time' => '1:00PM',
'end_time' => '1:30PM',
),
array(
'title' => 't1',
'start_time' => '1:30PM',
'end_time' => '2:00PM',
),
array(
'title' => 't1',
'start_time' => '3:15PM',
'end_time' => '3:45PM',
),
array(
'title' => 't1',
'start_time' => '3:45PM',
'end_time' => '4:45PM',
)
)
);


Based on the current time, i'm trying to find the next available time slot of at least 15 minutes. So say its currently 1:15PM, the next available time slot would be 2:00PM (based on the supplied array of data). This seems easy enough but i'm stumped.

The code below is where i'm at. It will return the title if there is an event taking place at the current time but i'm not really sure how to get the next time slot that is not being taken.

$time = time();
$timePlus15 = time() + 60*15;

foreach ($events->events as $key => $event) {
$start_time = strtotime($event->start_time);
$end_time = strtotime($event->end_time);

if (($time > $start_time && $timePlus15 < $end_time) || $time > $start_time && $time < $end_time || ($time < $start_time && $timePlus15 > $start_time && $timePlus15 < $end_time)) {
echo $event->title;
}
}


Basically, I want to loop through the array. If at the current time there is an event, increment the time by 15 minutes and check again. If there is an event, increment 15 minutes and check again, and repeat until there is no event for the time, then return that time.

the code is in php but i'll accept a javascript/jquery answer as well

** THE SOLUTION TO MY PROBLEM IS BELOW **

this.setNextAvailableTime = function() {
var requiredGap = 15 * 60 * 1000;
var events = app.rooms.events[app.rooms.current_room].events;
var prev = events[0];
var firstGap = null;
if (events.length === 1) {
firstGap = prev.end_24time;
} else {
for (var i = 1; i < events.length; i += 1) {

var current = events[i];

var current_start = new Date();
var prev_end = new Date();
current_start.setHours(events[i].start_24time.substring(0,2),events[i].start_24time.substring(3,5), 0);
prev_end.setHours(prev.end_24time.substring(0,2),prev.end_24time.substring(3,5), 0);

var diff = current_start.getTime() - prev_end.getTime();

if( diff >= requiredGap) {
firstGap = prev.end_24time;
break;
}

prev = current;
}
}
//do something with the firstGap time
$('#start_time').val(firstGap);
};

Answer

It's probably easier to see what the difference between the end of the first event, and the start of the next event is. Here's an example in javascript:

(note that the string to date conversion isn't very solid, it's just some test data)

var events = [{
  start: "2016-01-01T12:00",
  end: "2016-01-01T13:00"
}, {
  start: "2016-01-01T13:00",
  end: "2016-01-01T13:30"
}, {
  start: "2016-01-01T13:30",
  end: "2016-01-01T14:00"
}, {
  start: "2016-01-01T15:15",
  end: "2016-01-01T15:45"
}, {
  start: "2016-01-01T15:45",
  end: "2016-01-01T16:45"
}];

var dateEvents = events.map(function(event) {
  return {
    start: new Date(event.start),
    end: new Date(event.end)
  };
});

var requiredGap = 15 * 60 * 1000;
var prev = dateEvents[0];
var firstGap = null;

for (var i = 1; i < dateEvents.length; i += 1) {
  var current = dateEvents[i];
  var diff = current.start - prev.end;
  
  if (diff >= requiredGap) {
    firstGap = {
      start: prev.end,
      end: current.start
    };
    break;
  }
  
  prev = current;
}

if (firstGap != null) {
  console.log("First gap starts at: " + firstGap.start); 
} else {
  console.log("No gaps available");
}