I have a List<T>
of available times within a 24 hour day, and two TimeSpans
, minTime and maxTime.
I need to find a time of day within the List<T>
that lands between the minTime
and maxTime
, however due to this being used in multiple timezones, the minTime and maxTime can be on separate days and span something like 1pm to 1am the next day
The closest I've come to is this, but I feel like I am missing some major component here, or doing something really inefficient since I'm fairly new to the TimeSpan
object. I just can't figure out what...
// Make new TimeSpan out of maxTime to eliminate any extra days (TotalHours >= 24),
// then check if time on the MaxTime is earlier than the MinTime
if (new TimeSpan(maxTime.Hours, maxTime.Minutes, maxTime.Seconds) < minTime)
{
// If time on MaxTime is earlier than MinTime, the two times span separate days,
// so find first time after minTime OR before maxTime
nextAvailableTime = Times.FirstOrDefault(p =>
(p.Time.TimeOfDay >= minTime || (p.Time.TimeOfDay < maxTime))
&& p.Count < ConcurrentAppointments);
}
else
{
// If time on MaxTime is later than MinTime, the two times are for the same day
// so find first time after minTime AND before maxTime
nextAvailableTime = Times.FirstOrDefault(p =>
(p.Time.TimeOfDay >= minTime && p.Time.TimeOfDay < maxTime)
&& p.Count < ConcurrentAppointments);
}
The List of Times
uses EST (my local time), however the minTime
and maxTime
can be based on other time zones.
For example, if we ran this algorithm for a Hawaii time zone, we will end up having minTime = new TimeSpan(13, 0, 0)
and maxTime = new TimeSpan(25, 0, 0)
, since 8am - 8pm HST = 1pm - 1am EST.
The Times
collection is a List<AppointmentTime>
, and AppointmentTime
is a class looks like this:
class AppointmentTime
{
DateTime Time { get; set; }
int Count { get; set; }
}
I'm fairly sure I'm missing something major here, or that there should be a more efficient way of doing this that I'm not aware of, but I really can't think of what it could be. Is there something wrong with my algorithm? Or a more efficient way of finding a TimeOfDay
between two TimeSpans
that may span separate days?
Update
I figured out what I was missing based on CasperOne's answer. I was forgetting the date actually does matter since my times are going across different time zones.
Using my above example of the Hawaii time zone, scheduling appointments for Monday would result in incorrectly scheduling Hawaii appointments on Sunday night.
My solution was to check that the previous day was valid before scheduling appointments for the "first window" of the 24-hour day, and to adjust the appointment date by .AddDays(maxTime.Days)
when comparing with maxTime
// If time on MaxTime is earlier than MinTime, the two times span separate days,
// so find first time after minTime OR before maxTime if previous day has appointments set as well
var isPreviousDayValid = IsValidDate(AppointmentDate.AddDays(-1));
nextAvailableTime = Times.FirstOrDefault(p =>
(p.Time.TimeOfDay >= minTime
|| (p.Time.AddDays(maxTime.Days).TimeOfDay < maxTime && isPreviousDayValid)
) && p.Count < ConcurrentAppointments);
TimeSpan
object – SalukiminDate
is greater thanmaxDate
that it indicates a window of time across two days? – HijoungminDate
is never greater thanmaxDate
, howeverminDate.Hours
can be greater thanmaxDate.Hours
, in which case yes it would indicate a window of time across more than one day – SalukiminDate
andmaxDate
DateTime
structures with actual date components, or is the date irrelevant in them? IfminTime
is greater thanmaxTime
that's the indicator that the window is on the next day? – HijoungTimeSpan
objects, so the date is irrelevant however there are cases where you would have something likemaxDate = new TimeSpan(25, 30, 0)
because 8:30pm EST = 1:30am UTC – SalukiTimeSpan
is more than one day, then you have a window that overlaps a day, got it. – Hijoung