Problem:
I need to create an application with showing time slots for user.
I retrieve all events for day with Google API and let show example, already booked events:
const events = [
{ startTime: new Date('2023-10-18T00:00:00+0000'), endTime: new Date('2023-10-18T08:00:00+0000') },
{ startTime: new Date('2023-10-18T09:00:00+0000'), endTime: new Date('2023-10-18T10:00:00+0000') },
{ startTime: new Date('2023-10-18T11:00:00+0000'), endTime: new Date('2023-10-18T12:30:00+0000') },
{ startTime: new Date('2023-10-18T16:00:00+0000'), endTime: new Date('2023-10-18T17:30:00+0000') },
{ startTime: new Date('2023-10-18T18:00:00+0000'), endTime: new Date('2023-10-19T00:00:00+0000') },
];
and I want to create available time slots between these events with interval 15 minutes and meeting duration should be 60 minutes
so based on that events I would like to have output:
const availableSlots = ['8:00', '10:00', '12:30', '12:45', '13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30', '14:45', '15:00']
I need to create an application similar to booksy:
I tried something like that, but output is incorrect:
const meetingDuration = 60; // minutes
const interval = 15; // minutes
const workdayStart = new Date('2023-10-18T08:00:00'); // Start of workday
const workdayEnd = new Date('2023-10-18T17:00:00'); // End of workday
const availableSlots = [];
let currentSlotStart = new Date(workdayStart);
while (currentSlotStart < workdayEnd) {
const currentSlotEnd = new Date(currentSlotStart);
currentSlotEnd.setMinutes(currentSlotEnd.getMinutes() + meetingDuration);
if (events.every(event => (currentSlotStart < event.startTime && currentSlotEnd <= event.startTime) || (currentSlotEnd >= event.endTime && currentSlotEnd >= event.endTime))) {
availableSlots.push({ start: currentSlotStart.toUTCString(), end: currentSlotEnd.toUTCString() });
}
currentSlotStart = new Date(currentSlotStart);
currentSlotStart.setMinutes(currentSlotStart.getMinutes() + interval);
}
console.log(availableSlots);
Please help! 😀
Solution:
SUGGESTION
I’ve made a slight tweak to the main logic operation on your function to check if a booking slot is available.
From:
if (events.every(event => (currentSlotStart < event.startTime && currentSlotEnd <= event.startTime) || (currentSlotEnd >= event.endTime && currentSlotEnd >= event.endTime))) {
availableSlots.push({ start: currentSlotStart.toUTCString(), end: currentSlotEnd.toUTCString() });
}
To:
if (events.every(event => (currentSlotStart < event.startTime && currentSlotEnd <= event.startTime) || (currentSlotStart >= event.endTime))) {
availableSlots.push({ start: currentSlotStart.toUTCString(), end: currentSlotEnd.toUTCString() });
}
-
The 1st logic was unchanged, since it already checks if the current timestamp (both the start and endpoint) does not conflict with an existing event’s starting time (this also covers for future event booking conflicts)
-
I’ve changed the 2nd logic however, to just check if the current timestamp conflicts the ending point of a finished event; this is to validate that any finished events will not coincide with the booking time.
The full code snippet:
const meetingDuration = 60; // minutes
const interval = 15; // minutes
// just added UTC timezone stamp for consistency
const workdayStart = new Date('2023-10-18T08:00:00+0000'); // Start of workday
const workdayEnd = new Date('2023-10-18T17:00:00+0000'); // End of workday
const availableSlots = [];
let currentSlotStart = new Date(workdayStart);
while (currentSlotStart < workdayEnd) {
const currentSlotEnd = new Date(currentSlotStart);
currentSlotEnd.setMinutes(currentSlotEnd.getMinutes() + meetingDuration);
if (events.every(event => (currentSlotStart < event.startTime && currentSlotEnd <= event.startTime) || (currentSlotStart >= event.endTime))) {
availableSlots.push({ start: currentSlotStart.toUTCString() });
}
currentSlotStart = new Date(currentSlotStart);
currentSlotStart.setMinutes(currentSlotStart.getMinutes() + interval);
}
console.log(availableSlots);