Skip to content

Instantly share code, notes, and snippets.

@bolorundurowb
Created February 28, 2020 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bolorundurowb/76c0de78fef420b467681ddbdbc57b76 to your computer and use it in GitHub Desktop.
Save bolorundurowb/76c0de78fef420b467681ddbdbc57b76 to your computer and use it in GitHub Desktop.
A hacky system for finding all free time slots given a list of available periods and a list of booked periods
using System;
using System.Linq;
using System.Collections.Generic;
class MainClass
{
public static void Main(string[] args)
{
var daySlots = new List<Availability>
{
new Availability(DayOfWeek.Monday, new DateTime(2000, 1, 1, 9, 0, 0), new DateTime(2000, 1, 1, 12, 0, 0)),
new Availability(DayOfWeek.Monday, new DateTime(2000, 1, 1, 17, 0, 0), new DateTime(2000, 1, 1, 21, 30, 0))
};
var usedSlots = new List<Availability>
{
new Availability(DayOfWeek.Monday, new DateTime(2000, 1, 1, 9, 45, 0), new DateTime(2000, 1, 1, 10, 30, 0)),
new Availability(DayOfWeek.Monday, new DateTime(2000, 1, 1, 10, 30, 0),
new DateTime(2000, 1, 1, 10, 45, 0)),
new Availability(DayOfWeek.Monday, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 18, 20, 0)),
new Availability(DayOfWeek.Monday, new DateTime(2000, 1, 1, 20, 47, 0), new DateTime(2000, 1, 1, 21, 30, 0))
};
var freeTimes = GetDayOpenSlots(daySlots, usedSlots);
foreach (var freeTime in freeTimes)
{
Console.WriteLine("{0} - {1}", freeTime.StartTime, freeTime.EndTime);
}
}
private static List<Availability> GetDayOpenSlots(IEnumerable<Availability> daySlots,
IReadOnlyCollection<Availability> usedDaySlots)
{
var freeTimeBlocks = new List<Availability>();
foreach (var daySlot in daySlots)
{
var selectedSlotsWithinRange = usedDaySlots
.Where(x => x.StartTime >= daySlot.StartTime && x.EndTime <= daySlot.EndTime)
.OrderBy(x => x.StartTime)
.ToList();
if (!selectedSlotsWithinRange.Any())
{
freeTimeBlocks.Add(daySlot);
continue;
}
for (var i = 0; i < selectedSlotsWithinRange.Count - 1; i++)
{
var currentSlot = selectedSlotsWithinRange[i];
var nextSlot = selectedSlotsWithinRange[i + 1];
if (currentSlot.EndTime == nextSlot.StartTime)
{
continue;
}
freeTimeBlocks.Add(new Availability(daySlot.DayOfWeek, currentSlot.EndTime,
nextSlot.StartTime));
}
var firstAppointment = selectedSlotsWithinRange.First();
var lastAppointment = selectedSlotsWithinRange.Last();
if (firstAppointment.StartTime > daySlot.StartTime)
{
freeTimeBlocks.Add(new Availability(daySlot.DayOfWeek, daySlot.StartTime,
firstAppointment.StartTime));
}
if (lastAppointment.EndTime < daySlot.EndTime)
{
freeTimeBlocks.Add(new Availability(daySlot.DayOfWeek, lastAppointment.EndTime, daySlot.EndTime));
}
}
return freeTimeBlocks
.OrderBy(x => x.StartTime)
.ToList();
}
}
public class Availability
{
public int Id { get; private set; }
public DayOfWeek DayOfWeek { get; private set; }
public DateTime StartTime { get; private set; }
public DateTime EndTime { get; private set; }
private Availability()
{
}
public Availability(DayOfWeek dayOfWeek, DateTime startTime, DateTime endTime)
{
UpdateDayOfWeek(dayOfWeek);
UpdateStartTime(startTime);
UpdateEndTime(endTime);
}
public void UpdateDayOfWeek(DayOfWeek dayOfWeek)
{
DayOfWeek = dayOfWeek;
}
public void UpdateStartTime(DateTime startTime)
{
StartTime = startTime;
}
public void UpdateEndTime(DateTime endTime)
{
EndTime = endTime;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment