I am looking for help designing the display of available times for appointments (for example a hairdresser's appointment book).

Currently I have a query that returns a collection of periods that are unavailable for appointments (whether there is an existing appointment or if the service provider is closed).

So lets say Feb 3rd, from 12 to 5 is unavailable, i want to output the following string: Jan 1st 12 am - Feb 3rd 12pm Feb 3rd, 5pm - Dec 31 12 am.

My entire range is 1 year from Jan 1st to December 31st and there can be as many unavailable dates.

  • 2
    This question appears to be off-topic because it is asking for a specific implementation and is not a design or conceptual programming question. – user53019 Aug 27 '13 at 20:26
  • I didn't know how to put it as off-topic – Luca Aug 27 '13 at 20:31
  • It looks like he's asking for help with design. I've actually solved this problem. Storing gaps of closed times is one half of the solution. The other half is assuming that unless there is an unavailable slot, it's available. So now you start with Jan 1st and show everything as available until the first unavailable period. The next available period starts at the end of the first unavailable period and goes to the start of the second...etc. etc – Michael Brown Aug 27 '13 at 21:07
  • 1
    @MikeBrown - would you edit that into the question? I'd rather clarify the question and get it re-opened than to just leave it closed. Ping me when you're done editing and I'll vote to re-open. – user53019 Aug 28 '13 at 13:14
  • 1
    @GlenH7 I've made the edits. – Michael Brown Aug 29 '13 at 0:10

If overlap is not allowed, a rather simple process can be followed:

  • Add an appointment starting at 31 Dec 12 AM (ending any time).

  • Sort the appointments.

  • Initialize lastTime to 1 Jan 12 AM.

  • For each appointment:
    Output lastTime to the start of this appointment.
    Set lastTime = the end of this appointment.

If overlap is allowed, this requires a sweep-line algorithm:

  • Split the appointments into start and end times and sort them.
    If a start time and an end time are equal, put the start time first (otherwise you may get 0 duration outputs).

  • Add 31 Dec 12 AM as a start time.

  • Initialize lastTime to 1 Jan 12 AM.

  • Initialize a count variable to 0. This variable will, at any time, indicate how many appointments are busy at the current point in time.

  • Iterate through the times.

    If we encounter a start time:

    • If count = 0, output lastTime to this time.

    • Increment count.

    If we encounter an end time:

    • Decrement count.

    • Set lastTime to this time.

If the appointments can go beyond the given range, that should be simple enough to deal with:

For the first algorithm, start at the first appointment that ends after 1 Jan 12 AM and end before any appointment after 31 Dec 12 AM.

For the second, just initialize count to the number of appointments that runs through 1 Jan 12 AM and ignore points outside the given range.


Given your starting point the solution is pretty straight forward. Assume that you start with all times being available so your initial display will be:

Jan 1st 12:00am - Dec 31st 11:59pm

Assuming that the appointment times are in chronological order and there is no overlap with any of them (if not, you should be able to make an algorithm to fix up the list for you) the solution is simple.

For each "unavailable" slot:

  • Take the last available slot and split it into two
  • set the start time of the first slot to the start time of the original
  • set the end time of the first slot to the start time of the "unavailable" slot
  • set the start time of the second slot to the end time of the "unavailable" slot
  • set the end time of the second slot to the end time of the original.

Once you've down that you'll have a list of available slots. Here's an example:

Original availability is Jan 1st 12:00 AM - Dec 31st 11:59 PM

you have the following "unavailable" slots

Jan 15th 12:00 AM - Jan 15th 11:59 PM

Jan 20th 12:00 PM - Feb 4th 9:00 AM

Feb 14th 1:00 PM - Feb 14th 5:00 PM

The first run of the algorithm would look like so

Original Jan 1st 12:00 AM - Dec 31st 11:59 PM

Split into two

First runs Start of original to start of "unavailable"

Jan 1st 12:00 AM - Jan 15th 12:00 AM

Second runs End of "unavailable" to end of original

Jan 15th 11:59 PM - Dec 31st 11:59 PM

So now you have two available slots

Jan 1st 12:00 AM - Jan 15th 12:00 AM

Jan 15th 11:59 PM - Dec 31st 11:59 PM

Do the same operations with the next two and you're home free.

Don't forget edge cases.

What happens when you have an available slot that is essential zero in length? What happens when one of the "unavailable slots runs past the end or before the beginning of your window?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.