Rac*_*hel 6 .net c# timespan .net-4.0
我有List<T>24小时内的可用时间,以及两个TimeSpans,minTime和maxTime.
我需要找到内一天的时间List<T>,该之间土地minTime和maxTime,但是由于这个正在多个时区中使用时,minTime和MAXTIME可以在不同的日子和跨越像下午1点至凌晨1点,第二天
我最接近的就是这个,但我觉得我在这里缺少一些主要的组件,或者做一些非常低效的事情,因为我对这个TimeSpan对象很新.我只是无法弄清楚是什么......
// 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);
}
Run Code Online (Sandbox Code Playgroud)
名单Times用途EST(我的本地时间),但是minTime并maxTime可以根据其他时区.
例如,如果我们为夏威夷时区运行此算法,我们将最终拥有minTime = new TimeSpan(13, 0, 0)和maxTime = new TimeSpan(25, 0, 0),从早上8点 - 晚上8点HST =下午1点 - 美国东部时间凌晨1点.
该Times集合是一个List<AppointmentTime>,并且AppointmentTime是一个类如下:
class AppointmentTime
{
DateTime Time { get; set; }
int Count { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我相当肯定,我失去了一些东西主要这里,还是应该有这样做的,我是不知道的更有效的方式,但我真的不认为它可能是什么.我的算法有问题吗?或者更有效的方法来找到可能跨越不同日子的TimeOfDay两者之间TimeSpans?
更新
根据CasperOne的回答,我想出了我所缺少的东西.我忘了日期确实很重要,因为我的时间跨越不同的时区.
使用我上面的夏威夷时区示例,安排星期一的约会将导致在周日晚上错误地安排夏威夷约会.
我的解决方案是在为24小时工作日的"第一个窗口"安排约会之前检查前一天是否有效,并.AddDays(maxTime.Days)在与之比较时调整约会日期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);
Run Code Online (Sandbox Code Playgroud)
总的想法是,不要比较时间,要比较日期;将您的窗口从时间转换为日期,其余的就很容易了。
您可以为列表中的每个DateTime项目生成一组新的实例,以比较最小值和最大值,并使用该属性作为计算要比较的范围上限的基础。Date
这假设您的minTime始终小于maxTime,并且如果您的窗口覆盖超过一天,则通过在 上具有大于 24 小时的Hours属性值来表示重叠到新一天的范围。TimeSpan
你必须看看前一天和后天是否有一个窗口。例如:
(1) (2) (3) (4) (5)
----x----x----x----x----x----
(1) - 1/1/1900 11:00 PM - Date component in your list - 1 day + min time
(2) - 1/2/1900 12:05 AM - this is the date and time from your list
(3) - 1/2/1900 01:00 AM - Date component in your list - 1 day + max time
(4) - 1/2/1900 11:00 PM - Date component in your list + min time
(5) - 1/3/1900 01:00 AM - Date component in your list + max time
Run Code Online (Sandbox Code Playgroud)
这意味着您需要创建两个窗口并检查是否位于以下任一窗口中:
nextAvailableTime = Times.FirstOrDefault(p => {
// Check count first, get this out of the way.
if (!(p.Count < ConcurrentAppointments)) return false;
// The date time and the date component
DateTime dt = p.Time;
DateTime d = dt.Date;
// The windows
DateTime prevWindowMin = d.AddDays(-1) + minTime;
DateTime prevWindowMax = d.AddDays(-1) + maxTime;
DateTime windowMin = d + minTime;
DateTime windowMax = d + maxTime;
// Is it in *either* window;
return
(prevWindowMin <= dt && dt <= prevWindowMax)||
(windowMin <= dt && dt <= windowMax);
});
Run Code Online (Sandbox Code Playgroud)
从您的问题中尚不完全清楚,但是如果一天中的时间不是列表Date中项目的组成部分,您可以替换该p.Time日期的Date组成部分(根据需要减去一天来创建窗口),并且它应该工作。