这应该是您要找的内容。我决定重命名您的类,因为C#中已经有一个Task类。此外,我使它具有工厂方法以便您可以对值进行一些检查。还请注意需要从DateTime使用的DayOfWeek枚举映射到您的WeekDays枚举。基本上,您需要迭代存在于两个DateTime之间的每一天,以查看应从总持续时间中删除多少时间。
public class ScheduledTask
{
private ScheduledTask() { }
public static ScheduledTask CreateTask(TimeSpan start, TimeSpan end, WeekDays days)
{
if (start < TimeSpan.Zero || start >= TimeSpan.FromDays(1))
{
throw new ArgumentOutOfRangeException("start");
}
if (end < TimeSpan.Zero || end >= TimeSpan.FromDays(1))
{
throw new ArgumentOutOfRangeException("end");
}
if (start > end)
{
throw new ArgumentException("End cannot be before Start", "end");
}
if ((int)days < 1 || (int)days >= 128)
{
throw new ArgumentOutOfRangeException("days");
}
return new ScheduledTask { Start = start, End = end, Days = days };
}
public WeekDays Days { get; private set; }
public TimeSpan Start { get; private set; }
public TimeSpan End { get; private set; }
public TimeSpan DifferenceMinusTaskTime(DateTime from, DateTime to)
{
var actualFrom = from;
var actualTo = to;
if (from > to)
{
actualFrom = to;
actualTo = from;
}
TimeSpan duration = TimeSpan.Zero;
DateTime dayStart = actualFrom;
DateTime dayEnd = actualFrom.Date == actualTo.Date
? actualTo
: actualFrom.Date.AddDays(1);
bool endIsNextDay = dayEnd.Date > dayStart.Date;
while (dayStart < actualTo)
{
duration += dayEnd - dayStart;
if (Days.HasFlag(mapping[dayStart.DayOfWeek])
&& dayStart.TimeOfDay < End
&& (dayEnd.TimeOfDay > Start || endIsNextDay))
{
if (dayStart.TimeOfDay < Start)
{
if (dayEnd.TimeOfDay > End || endIsNextDay)
{
duration -= End - Start;
}
else
{
duration -= dayEnd.TimeOfDay - Start;
}
}
else
{
if (dayEnd.TimeOfDay > End || endIsNextDay)
{
duration -= End - dayStart.TimeOfDay;
}
else
{
duration -= dayEnd - dayStart;
}
}
}
dayStart = dayEnd;
dayEnd = dayStart.Date == actualTo.Date
? actualTo
: dayStart.Date.AddDays(1);
endIsNextDay = dayEnd.Date > dayStart.Date;
}
return from > to ? TimeSpan.Zero - duration : duration;
}
private Dictionary<DayOfWeek, WeekDays> mapping =
new Dictionary<DayOfWeek, WeekDays>
{
{ DayOfWeek.Monday, WeekDays.Monday },
{ DayOfWeek.Tuesday, WeekDays.Tuesday },
{ DayOfWeek.Wednesday, WeekDays.Wednesday },
{ DayOfWeek.Thursday, WeekDays.Thursday },
{ DayOfWeek.Friday, WeekDays.Friday },
{ DayOfWeek.Saturday, WeekDays.Saturday },
{ DayOfWeek.Sunday, WeekDays.Sunday }
};
}
使用上面的代码,得到以下结果。
var task = ScheduledTask.CreateTask(
TimeSpan.FromHours(2),
TimeSpan.FromHours(8),
WeekDays.Monday | WeekDays.Tuesday | WeekDays.Wednesday);
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24),
new DateTime(2015, 8, 27)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 27),
new DateTime(2015, 8, 24)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 28),
new DateTime(2015, 8, 29)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24),
new DateTime(2015, 8, 24, 10, 0, 0)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24),
new DateTime(2015, 8, 24, 4, 0, 0)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24, 4, 0, 0),
new DateTime(2015, 8, 24, 6, 0, 0)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24, 4, 0, 0),
new DateTime(2015, 8, 24, 10, 0, 0)));
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24, 10, 0, 0),
new DateTime(2015, 8, 24, 14, 0, 0)));
将输出
2.06:00:00
-2.06:00:00
1.00:00:00
04:00:00
02:00:00
00:00:00
02:00:00
04:00:00
task.Days = WeekDays.Monday | WeekDays.Tuesday | WeekDays.Wednesday
比task.Days = 7
更易读。 - juharr