c#DateTime范围不包括特定范围

use*_*430 5 c# enums datetime

我有一个Flags Enum:

[Flags]
public enum WeekDays
{

    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64
}
Run Code Online (Sandbox Code Playgroud)

然后是一堂课

public class Task
{
     public Task()
     {

     }

     public int Days { get; set; }
     public TimeSpan Start { get; set; }
     public TimeSpan End { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

假设以下值

 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
Run Code Online (Sandbox Code Playgroud)

和特定的范围期间:

 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
Run Code Online (Sandbox Code Playgroud)

如何从totalSeconds任务中减去totalSeconds

所以基本上我想从totalSeconds中排除任务发生的时间段,即每周一,周二,周三00:00到06:00,即3x6hours = 18小时,即64800秒?

我需要通过将掩码应用到时间范围来做到这一点......

juh*_*arr 1

这应该就是您正在寻找的。Task我决定重命名你的类,因为C# 中已经有一个类了。此外,我还为其创建了工厂方法,因为您想对值进行一些检查。另请注意,需要从DayOfWeek所使用的枚举DateTime到您的WeekDays枚举的映射。基本上,您需要迭代两个DateTimes 之间存在的每一天,以查看应从总持续时间中删除多少时间。

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 }
        };
}
Run Code Online (Sandbox Code Playgroud)

有了上面的下面的

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
Run Code Online (Sandbox Code Playgroud)

将输出

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