ok so this should be simple really but seems I can’t get my head around it.
I have a table called Dates which has a listing of all dates starting 2012 until its very end. Now when a customer makes reservation, I need to take starting date and ending date, generate the range between them in datetime format, and check each against its equivalent date in table to see capacity. if so, then decrement the capacity by booking requirement.
so far I have this code:
private List<DateTime> getDateRange(DateTime startDate, DateTime endDate)
{
if (startDate > endDate)
{
return null;
}
List<DateTime> rv = new List<DateTime>();
DateTime tmpDate = startDate;
do
{
rv.Add(tmpDate);
tmpDate = tmpDate.AddDays(1);
} while (tmpDate <= endDate);
return rv;
}
The code is supposed to generate a list with dates in range and is called later in this function:
public void checkDateRange(DateTime startDate, DateTime endDate)
{
//need to check each element in the list against the table DateTest:
//changing the parameters of parse will give error. Require type handling
//First, extract the elements:
DateTime StartingDate = DateTime.Parse("02/25/2007");
DateTime EndingDate = DateTime.Parse("03/06/2007");
foreach (DateTime date in getDateRange(StartingDate, EndingDate))
{
date.ToShortDateString();
}
//rest of code should go here...
}
am thinking more like retrieve whole set from table DateTest, then in a loop (not sure which) I would go about checking if x = y these are the dates. Any code illustration would be highly appreciated. Regards,
I haven’t looked at your code, but here are a few comments:
TimeSpan, not aDateTimeStartDateorEndDate, you can add or subtract theTimeSpanwith the other valueHere is how to do a 1-dimensional intersection test:
One-Dimensional Line-Segments/Ranges Intersection Test: Solution Name?
Once you have validated that there is an overlap between two date ranges, here is a way to calculate that overlap:
With these checks in hand, I have a potential solution for you.
Potential Solution
You can make a special data structure that doesn’t contain individual appointments, but instead contains all consumed capacity.
When you add a reservation to this data structure, you check if the new value overlaps existing reservations. You calculate its intersection between all existing values. For each value that it overlaps, add just the overlapped portion to a list, including the currently booked capacity at that overlap.
Once all overlaps have been calculated, check if any of the items in the list have reached max capacity. If they have, then the booking is invalid, because it will make you over capacity. If they haven’t you can add the reservation.
To add the reservation, increment all the intersection values’ booking counts by one. Then remove all existing values in the data structure on the range of the reservation. Split items if necessary to remove only the overlapped portion. When you are done, add the incremented intersections back into the list.
You can do a similar but reversed operation when removing a booking, but you’ll have to merge bookings back together at the end/beginning of the range instead of splitting them apart.
Or you can model this the opposite way, subtracting available capacity. Whichever makes more sense to you.
This model will work well with modelling variable capacity because you can model your capacity with a similar data structure. You’d just do additional intersection tests between consumed capacity and available capacity, ensuring you always have enough available capacity to satisfy the booked capacity.
I would be careful to design a system where this wasn’t the only data I relied on, and I could regenerate this data from data in a separate structure/table. For example, I would store the start and end dates and contact information for each booking separately.
Optimization
You can take advantage of sorting and space partitioning algorithms to speed up the part where you compare against all booked values. For example, you could partition out all the values into month-long chunks, so you only have to compare against the one or two months that your booking intersects. In relational database land this is called temporal partitioning.
If you choose to do partitioning, one requirement that can make your life simpler is to make sure your partitions are large enough that you will only ever need to check two cells. Make your partitions smaller than this, and your algorithm will be more complicated and therefore harder to verify.
If your data is small enough, you could calculate this whole table on the fly for just the date range you are interested in, rather than storing the data structure in the database. You might also not have to worry about partitioning if your ranges are small enough that you can stand to check every day (or whatever unit, if you have a different resolution) within the range. This would allow you to simplify some of the operations because you can just build up your data structure and do your capacity check, and you won’t have to worry about things like splitting up or merging capacity ranges.