I'm trying to get times of available slots. I have startDateTime, endDateTime, duration, and bufferBetweenSlots fields in my db. with some calculations I have figured out number of available slots.
the value of fields are:
startDateTime: 8/20/2021 11:30 AM
endDateTime: 8/20/2021 9:30 PM
duration: 60
bufferBetweenSlots: 30
but I'm not sure how to get the start and end time for the available slots. e.g. 10:00 - 11:00
const getTimeDiffInMins = (endTime, startTime) =>
(+new Date(endTime) - +new Date(startTime)) / (60 * 1000);
const getMultipleTimeSlots = (data) => {
const diff = getTimeDiffInMins(data.end_date_time, data.start_date_time);
const totalSlots = diff / data.duration;
const totalBuffer = data.buffer_between_slots * totalSlots;
const availableSlots = (diff - totalBuffer) / 60;
return availableSlots;
};
any suggestions?
You should only need a buffer between slots, so the number of buffers is one less than the number of slots, i.e. you want to solve:
n * slotTime + (n - 1) * bufferTime == totalTime
such that:
totalTime <= diff
You can do that by adding the buffer to totalTime and dividing by slotTime + bufferTime, then flooring the result to get the whole number of available slots plus buffers. Then you can just iterate to produce the required start and end time. E.g.
let startDateTime = new Date(2021,7,8,11,30); // 20 Aug 2021 11:30
let endDateTime = new Date(2021,7,8,22); // 20 Aug 2021 22:00
let duration = 60; // minutes
let bufferBetweenSlots = 30; // minutes
let diff = (endDateTime - startDateTime) / 6e4; // minutes
let numberOfSlots = Math.floor((diff + bufferBetweenSlots) / (duration + bufferBetweenSlots)); // minutes
let slots = [];
let time = new Date(startDateTime);
for (let i = 0; i < numberOfSlots; i++) {
// Add the slot start time
slots[i] = {start: time.toString()};
// Increment time to end of slot
time.setMinutes(time.getMinutes() + duration);
// Add the end time
slots[i].end = time.toString();
// Increment time to end of buffer
time.setMinutes(time.getMinutes() + bufferBetweenSlots);
}
console.log(slots);
I changed the end time to 22:00 to show it only puts in full slots. Whether you push timestamps or Date objects into the slots array is up to you. Just remember, if adding dates, to copy the date like:
slots[i] = {start: new Date(+time)};
...
slots[i].end = new Date(+time);
Thanks @RobG for taking the time to answer. here's how I managed to slove it.
const getTimeDiffInMins = (endTime, startTime) =>
(+new Date(endTime) - +new Date(startTime)) / (60 * 1000);
const convertToMilliSecs = (value) => value * 60 * 1000;
// coming from the db
const data = {
duration: 60,
buffer_between_slots: 30,
start_date_time: '2021-08-20T10:30:00Z',
end_date_time: '2021-08-20T20:30:00Z',
};
const {
duration: a,
buffer_between_slots: b,
end_date_time: x,
start_date_time: y,
} = data;
const duration = getTimeDiffInMins(x, y);
const slotDuration = a;
const totalSlots = a + b;
const numberOfSlots = Math.floor(duration / totalSlots);
const slotsAvailable = [...Array(numberOfSlots).keys()].map((slotNumber) => {
const slotStart = (slotNumber - 1) * totalSlots;
const slotEnd = slotStart + slotDuration;
return {
start: +new Date(y) + convertToMilliSecs(slotStart),
end: +new Date(y) + convertToMilliSecs(slotEnd),
};
});
/*
Now we can format the time however we want
I'm using momentjs:
moment(new Date(slot.start)).format('h:mma')
*/
console.log(slotsAvailable);