Reputation: 833
For a given span of time, say 2013-01-01 08:00 and 2013-01-02 08:00 (24 hours), over time someone may have sequentially entered records to indicate that they are available or not available. Where time spans overlap for a newly entered record, only different types (available or unavailable) are allowed. Availability records are preserved when changes occur.
How can I determine whether a given span of time is fully available?
For example, I may have the following records:
RecId | Start DateTime | End DateTime | Type
=====================================================
1 | 2013-01-01 08:00 | 2013-01-02 08:00 | Available
2 | 2013-01-01 08:00 | 2013-01-02 08:00 | Unavailable
3 | 2013-01-01 17:00 | 2013-01-02 08:00 | Available
4 | 2013-01-01 08:00 | 2013-01-02 17:00 | Available
5 | 2013-01-01 12:00 | 2013-01-02 14:00 | Unavailable
Given the records above, the individual is currently available on 2013-01-01 from 08:00 to 12:00, and 14:00 to 0800 the following morning.
I now want to check if the individual is available from, say, 2013-01-01 11:00 to 2013-01-01 15:00. The answer should be no, since the records indicate the individual is not available from 12:00 to 14:00 on that date.
If it helps, the application is to see whether someone is eligible to trade all or part of their scheduled shift with another employee. Multiple trades of different parts of the shift may be made with other individuals. Someone may trade their entire shift away, then work parts of that shift for other people, as long as parts don't overlap. We need to be able to check, when a new trade is scheduled, that the employees are actually free to trade for the block of time requested.
Upvotes: 3
Views: 2322
Reputation:
You can use the Time Period Library for .NET to calculate overlapping and intersecting time periods.
Upvotes: 2
Reputation: 8921
If I understand your question, fully available = contiguously available, i.e. with no intervening unavailable record slots. In other words, someone available 9Am to 5PM on some date but who also has a record saying unavailable from 2PM to 4PM on the same date, is NOT available from 9AM to 5PM on that date.
So, to find out if someone is available for a given desired span, you check to see that no unavailable span begins or ends within that desired span, and check to see if an available span begins before that desired span begins or coeval with it, and ends at the end of the desired span or after the end of the desired span.
P.S. You would also have to make sure that the desired span does not fall within an Unavailable span.
P.P.S. The complexity --or lack of simplicity-- is created by your use of beginning and ending spans of availability and unavailability which can overlap; an alternative is to create entities that stand for time slots of the day (perhaps the smallest being a quarter-hour) and for each slot per person you know whether the person is available for that slot or not. Then you can query the database and require that EACH slot within a given range of slots have status= AVAILABLE.
Upvotes: 1
Reputation: 21251
You seem to be recording three states (available, unavailable, and undefined), when only two are required (available or unavailable).
If you make the default state that a person is unavailable (since they won't be at work most of the time), then all you need to maintain are the periods of availability. This makes it trivial to check if a slot is free.
If a slot is free, then you just create new periods of availability if any of that slot is still free after a trade.
Upvotes: 0
Reputation: 4168
Abstract the entries of the record into a list of objects with structures like:
class AvailableSlot
{
public DateTime start;
public DateTime end;
}
Now you can use LINQ to address your problem:
var availableSlots = new List<AvailableSlot>();
//Read the record file and populate availableSlots
DateTime inputStart = DateTime.Now;
DateTime inputEnd = DateTime.Now.AddHours(2);
var isAvailable = availableSlots.Any(a => a.start <= inputStart && a.end >= inputEnd);
Upvotes: 0