I am trying to build a tool that calculates something called quota based upon when employees are scheduled to work and when they request off.
My ShiftSet object is a set of Shift objects which consist of a StartTime and EndTime (both of type time(7). Each ShiftSet corresponds to a day.
ScheduleExceptions are times that an employee has off. There can be any number of overlapping or non-overlapping ScheduleExceptions in a day. They are of the datetime data type.
An example of a ShiftSet:
08:00-10:00
10:00-12:00
13:00-15:00
15:00-17:00
An example of ScheduleExceptions for that same day:
07:30-10:30
14:35-16:00
What I need to do is to find the amount of time that the employee is working on a day. The way I can figure to do this is to calculate the intersection of ShiftSet and the inverse of ScheduleExceptions.
How would I do this with time? I would prefer to use Linq if possible.
Check out this great article at CodeProject
It's probably way too broad for your specific problem but it will probably give you a good starting point on how to solve it.
As InBetween mentioned, there are libraries out there that have solved this problem, but they solve many related problems as well. If you are wanting to just tackle this particular problem without taking on another dependency, you can try the following.
// Finds ones with absolutely no overlap
var unmodified = shifts.Where(s => !exceptions.Any(e => s.Start < e.End && s.End > e.Start));
// Finds ones entirely overlapped
var overlapped = shifts.Where(s => exceptions.Any(e => e.End >= s.End && e.Start <= s.Start));
// Adjusted shifts
var adjusted = shifts.Where(s => !unmodified.Contains(s) && !overlapped.Contains(s))
.Select(s => new Shift
{
Start = exceptions.Where(e => e.Start <= s.Start && e.End > s.Start).Any() ? exceptions.Where(e => e.Start <= s.Start && e.End > s.Start).First().End : s.Start,
End = exceptions.Where(e => e.Start < s.End && e.End >= s.End).Any() ? exceptions.Where(e => e.Start < s.End && e.End >= s.End).First().Start : s.End
});
var newShiftSet = unmodified.Union(overlapped).Union(adjusted);
It's a basic example, though it could be compacted (albeit less-readable) and improved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With