I have a Flags Enum:
[Flags]
public enum WeekDays
{
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64
}
and then a 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 specific range period:
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 substract from the totalSeconds the task's totalSeconds?
So basically I want to exclude from the totalSeconds the period when the task occures which is every Monday, Tuesday, Wednesday between 00:00 and 06:00 which is 3x6hours = 18 hours which is 64800 seconds?
I need to do this by applying the mask to the time range ...
This should be what you are looking for. I decided to rename your class because there is already a Task class in C#. Also I made it have factory method for creation as you want to do some checks on the values. Also note the need for a mapping from the DayOfWeek enum used by DateTime to your WeekDays enum. Basically you need to iterate through each day that exists between the two DateTimes to see how much time should be removed 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 the above the following
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
will output
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With