Daniel_Kamel
Daniel_Kamel

Reputation: 619

get first available time in a day that is not conflicting with an array of hours

I'm trying to get first available time either hour or hour and a half (will explain what I mean by hour and a half in an example) in a given day when I have other non-available hours in javascript.

Example #1:

If the current time is 8:45am and the unavailable hours are between "7:00am and 8:00am" + "10:00am and 11:00am" the first available time would be 9:00am.

Example#2:

If the current time is 1:35pm and the unavailable hours are between "2:00pm and 3:00pm" then the first available time is 3:30pm

Example #3:

If the current time is 11:00pm and the unavailable hours are between "11:30pm and 1:00pm" + "1:30pm and 2:00pm" then the first available time is 2:30pm

Upvotes: 1

Views: 64

Answers (1)

Terry Lennox
Terry Lennox

Reputation: 30685

I'd suggest creating a function getFirstAvailableTime() to search for the desired time.

We'd start at now plus one minute, then iterate through each timeslot, checking each one to see if it overlaps any of our unavailable timeslots.

If it does not overlap an unavailable timeslot we return it as the first available time.

function getFirstAvailableTime(now, unavailable, timeSlotSize = 30) {
    // Start at the first available timeslot _after_ now. 
    const start = Math.ceil((minutes(now) + 1) / timeSlotSize) * timeSlotSize;
    for (let min = start; min < 1440; min += timeSlotSize) {
        if (!unavailable.find(({ start, end }) => (min >= minutes(start) && min <= minutes(end)))) {
            return { hour: Math.floor(min / 60), minute: min % 60 };
        }
    }
}

function minutes( { hour, minute }) {
    return hour * 60 + minute;
}

function formatTime({ hour, minute }) { 
    return [hour, minute].map(n => (n + '').padStart(2, '0')).join(':');
}

function formatSpan({ start, end }) { 
    return [formatTime(start), formatTime(end)].join(' - ');
}

const inputs = [{ now: { hour: 8, minute: 45 }, unavailable: [{ start: { hour: 7, minute: 0}, end: { hour: 8, minute: 0} } ] },{ now: { hour: 13, minute: 35 }, unavailable: [{ start: { hour: 14, minute: 0}, end: { hour: 15, minute: 0} } ] },{ now: { hour: 11, minute: 0 }, unavailable: [{ start: { hour: 11, minute: 30}, end: { hour: 13, minute: 0} },{ start: { hour: 13, minute: 30}, end: { hour: 14, minute: 0} } ] } ]

console.log('Now'.padEnd(10, ' '), 'Unavailable'.padEnd(32, ' '), 'Next Slot');
for(let input of inputs) {
    console.log(formatTime(input.now).padEnd(10, ' '), input.unavailable.map(formatSpan).join(', ').padEnd(32, ' '), formatTime(getFirstAvailableTime(input.now, input.unavailable)))
}
.as-console-wrapper { max-height: 100% !important; }

Upvotes: 1

Related Questions