This should be what you are looking for. I decided to rename your class because C # already has a Task class. I also made a factory method for this to create, since you want to do some value checking. Also note the need to match the DayOfWeek enumeration used by DateTime for your WeekDays enumeration. Basically you need to iterate over every day that exists between two DateTime to find out how much time you need to remove from the total duration.
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 } }; }
With above below
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))); // 2 days 6 hours Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 27), new DateTime(2015, 8, 24))); // -2 days 6 hours Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 28), new DateTime(2015, 8, 29))); // 1 day Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 24), new DateTime(2015, 8, 24, 10, 0, 0))); // 4 hours Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 24), new DateTime(2015, 8, 24, 4, 0, 0))); // 2 hours Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 24, 4, 0, 0), new DateTime(2015, 8, 24, 6, 0, 0))); // 0 hours Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 24, 4, 0, 0), new DateTime(2015, 8, 24, 10, 0, 0))); // 2 hours Console.WriteLine( task.DifferenceMinusTaskTime( new DateTime(2015, 8, 24, 10, 0, 0), new DateTime(2015, 8, 24, 14, 0, 0))); // 4 hours
displays
2.06: 00: 00
-2.06: 00: 00
1.00: 00: 00
4:00:00
2:00:00
00:00:00
2:00:00
4:00:00