C# 如何查找datetime范围中缺少的datetime

C# 如何查找datetime范围中缺少的datetime,c#,C#,我在C#方面是个新手,在某种逻辑上我有一个日期范围(假设一个月,即2018-06-01到2018-06-30) 我有一份小范围约会的清单: STARTDATE ENDDATE 2018-06-04 2018-06-06 2018-06-11 2018-06-14 2018-06-17 2018-06-20 假设需要将上述日期从原始的一个月范围(2018-06-01至2018-06-30)中阻止。因此,作为输出,我需要一些逻辑来返回未被阻止的可用日期范围 因此,输出需要如下所示: STARTD

我在C#方面是个新手,在某种逻辑上我有一个日期范围(假设一个月,即2018-06-01到2018-06-30)

我有一份小范围约会的清单:

STARTDATE  ENDDATE
2018-06-04 2018-06-06
2018-06-11 2018-06-14
2018-06-17 2018-06-20
假设需要将上述日期从原始的一个月范围(
2018-06-01至2018-06-30)中阻止。因此,作为输出,我需要一些逻辑来返回未被阻止的可用日期范围

因此,输出需要如下所示:

STARTDATE  ENDDATE
2018-06-01 2018-06-03
2018-06-07 2018-06-10
2018-06-15 2018-06-16
2018-06-18 2018-06-19
2018-06-21 2018-06-30
因此,我需要一些C#专家指导我应该如何实现这一点。我不是要代码,但如果有人写了类似的逻辑,那么请分享想法或提供任何相同的参考


我主要关心的是我应该使用列表、字典、数据表还是其他什么?

你可以使用Linq,除了
FilteredList=BiggerList.except(SmallerList).ToList()
我会选择排除日期的列表,允许日期的列表。 然后,正如@PiJei所说的,只需按排除的日期过滤该月的列表


我借鉴了皮杰的建议。然后用一种方法扩展该方法,以获得起始范围内的天数,并用一种方法构建日期的最终范围

首先,让我们构建示例数据: var月=每一天(开始、结束)

为了做到这一点,我每天都在使用借用的
方法

最后,我使用这个列表并构建结果的范围

var ranges = GetRanges(withoutExcluded);
为此,我创建了一个简单的助手
Range
类和
GetRanges
方法,用于分析日期,如果它们是连续的日期,则构建单个范围

助手
范围
类:

public class Range
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}
助手
GetRanges
方法:

public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
{
    var start = dates.First();
    var end = dates.First();

    var prev = dates.First();
    var next = DateTime.Now;

    foreach(var d in dates.Skip(1))
    {
        next = d;
        var diff = next - prev;
        if (diff.TotalDays > 1)
        {
            yield return new Range { Start = start, End = end };
            start = d;   
        }

        prev = d;
        end = d;
    }

    yield return new Range { Start = start, End = end };
}
我将把结果的适当格式留给您。但逻辑是正确的。 如果您不知道下面我粘贴整个解决方案时会发生什么情况:

class Program
{
    static void Main(string[] args)
    {
        var start = new DateTime(2018, 06, 01);
        var end = new DateTime(2018, 06, 30);

        var month = EachDay(start, end);

        var start1 = new DateTime(2018, 06, 04);
        var end1 = new DateTime(2018, 06, 06);
        var sub1 = EachDay(start1, end1);

        var start2 = new DateTime(2018, 06, 11);
        var end2 = new DateTime(2018, 06, 14);
        var sub2 = EachDay(start2, end2);

        var start3 = new DateTime(2018, 06, 17);
        var end3 = new DateTime(2018, 06, 20);
        var sub3 = EachDay(start3, end3);

        var withoutExcluded = month.Except(sub1).Except(sub2).Except(sub3);
        var ranges = GetRanges(withoutExcluded);

        foreach (var r in ranges)
        {
            Console.WriteLine($"range: {r.Start} {r.End}");
        }
    }

    //https://stackoverflow.com/a/1847601/3330348
    public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
    {
        for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
            yield return day;
    }

    public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
    {
        var start = dates.First();
        var end = dates.First();

        var prev = dates.First();
        var next = DateTime.Now;

        foreach (var d in dates.Skip(1))
        {
            next = d;
            var diff = next - prev;
            if (diff.TotalDays > 1)
            {
                yield return new Range { Start = start, End = end };
                start = d;
            }

            prev = d;
            end = d;
        }

        yield return new Range { Start = start, End = end };
    }

    public class Range
    {
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var开始=新日期时间(2018年6月1日);
var end=新日期时间(2018年6月30日);
var月=每一天(开始、结束);
var start1=新的日期时间(2018,06,04);
var end1=新的日期时间(2018,06,06);
var sub1=每一天(开始1,结束1);
var start2=新的日期时间(2018,06,11);
var end2=新的日期时间(2018,06,14);
var sub2=每一天(开始2,结束2);
var start3=新的日期时间(2018,06,17);
var end3=新日期时间(2018年6月20日);
var sub3=每一天(开始3,结束3);
var WithoutExclude=月份。除(子1)。除(子2)。除(子3);
var范围=GetRanges(不排除);
foreach(范围内的var r)
{
WriteLine($“范围:{r.Start}{r.End}”);
}
}
//https://stackoverflow.com/a/1847601/3330348
公共静态IEnumerable EachDay(日期时间从,日期时间到)
{
对于(var日=起始日期;日期1)
{
产生返回新范围{Start=Start,End=End};
开始=d;
}
prev=d;
end=d;
}
产生返回新范围{Start=Start,End=End};
}
公共类范围
{
公共日期时间开始{get;set;}
公共日期时间结束{get;set;}
}
}

可能重复的I可能会使用a来执行您试图执行的操作。您似乎在寻找的逻辑是,只需从所述月份的第一个日期开始,循环浏览“次要日期范围”列表并检查开始日期
如果月初不等于“次要日期范围”中的第一个元素,则您有
开始日期的第一个元素,您可以继续循环天数以查找第一个间隔的
结束日期。冲洗并重复到月底。我认为您示例中结果中的范围不正确:
2018-06-18 2018-06-19
不确定,范围不是单元组或单元格。可以说,STARTDATE和ENDDATE是不同的列或字段。
public class Range
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}
public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
{
    var start = dates.First();
    var end = dates.First();

    var prev = dates.First();
    var next = DateTime.Now;

    foreach(var d in dates.Skip(1))
    {
        next = d;
        var diff = next - prev;
        if (diff.TotalDays > 1)
        {
            yield return new Range { Start = start, End = end };
            start = d;   
        }

        prev = d;
        end = d;
    }

    yield return new Range { Start = start, End = end };
}
range: 01/06/2018 00:00:00 03/06/2018 00:00:00
range: 07/06/2018 00:00:00 10/06/2018 00:00:00
range: 15/06/2018 00:00:00 16/06/2018 00:00:00
range: 21/06/2018 00:00:00 30/06/2018 00:00:00
class Program
{
    static void Main(string[] args)
    {
        var start = new DateTime(2018, 06, 01);
        var end = new DateTime(2018, 06, 30);

        var month = EachDay(start, end);

        var start1 = new DateTime(2018, 06, 04);
        var end1 = new DateTime(2018, 06, 06);
        var sub1 = EachDay(start1, end1);

        var start2 = new DateTime(2018, 06, 11);
        var end2 = new DateTime(2018, 06, 14);
        var sub2 = EachDay(start2, end2);

        var start3 = new DateTime(2018, 06, 17);
        var end3 = new DateTime(2018, 06, 20);
        var sub3 = EachDay(start3, end3);

        var withoutExcluded = month.Except(sub1).Except(sub2).Except(sub3);
        var ranges = GetRanges(withoutExcluded);

        foreach (var r in ranges)
        {
            Console.WriteLine($"range: {r.Start} {r.End}");
        }
    }

    //https://stackoverflow.com/a/1847601/3330348
    public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
    {
        for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
            yield return day;
    }

    public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
    {
        var start = dates.First();
        var end = dates.First();

        var prev = dates.First();
        var next = DateTime.Now;

        foreach (var d in dates.Skip(1))
        {
            next = d;
            var diff = next - prev;
            if (diff.TotalDays > 1)
            {
                yield return new Range { Start = start, End = end };
                start = d;
            }

            prev = d;
            end = d;
        }

        yield return new Range { Start = start, End = end };
    }

    public class Range
    {
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }
}