C # Range DateTime excludes certain ranges

I have an enumeration of flags:

[Flags] public enum WeekDays { Monday = 1, Tuesday = 2, Wednesday = 4, Thursday = 8, Friday = 16, Saturday = 32, Sunday = 64 } 

and then class

 public class Task { public Task() { } public int Days { get; set; } public TimeSpan Start { get; set; } public TimeSpan End { get; set; } } 

Assuming the following values

  Task task = new Task(); task.Days = 7; // from WeekDays enum: 7 = Monday, Tuesday, Wednesday task.Start = TimeSpan.Parse("00:00"); //midnight task.End = TimeSpan.Parse("06:00"); //morning 06 AM 

and a certain period of the range:

  DateTime now = DateTime.Now; DateTime start = now.AddDays(-6); TimeSpan time = now - start; double toatlSeconds = time.TotalSeconds; // get total seconds between the start and now datetime range 

How can I subtract the totalSeconds task from totalSeconds ?

So, basically, I want to exclude from the totalSeconds the period when a task occurs that occurs every Monday, Tuesday, Wednesday between 00:00 and 06:00, which is 3x6 hours = 18 hours, which is 64800 seconds?

I need to do this by applying a mask to the time range ...

+5
source share
1 answer

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

+1
source

All Articles