如何找到日期时间范围内缺少的日期时间

时间:2018-08-22 15:35:29

标签: 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 to 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#专家指南以了解如何实现此目标。我不是在问代码,但是也许如果有人写了类似的逻辑,那么请分享这个想法或提供任何参考。

我主要关心的是我应该使用列表,字典,数据表还是其他东西?

3 个答案:

答案 0 :(得分:0)

您可以使用Linq,但FilteredList = BiggerList.Except(SmallerList).ToList()

除外

答案 1 :(得分:0)

我会列出排除日期的列表,列出允许日期的列表。 然后如@PiJei所说,只需按排除日期过滤月份列表即可。

https://dotnetfiddle.net/2fv8bY

答案 2 :(得分:0)

我从皮杰的建议中借来了。然后使用方法扩展该范围以获取起始范围的日期,并使用一种方法构建日期的最终范围。

首先,让我们构建示例数据:     var month = EveryDay(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);

为此,我使用的是从this answer借来的EachDay方法。

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;
}

要获得我称为withoutExcluded的最终列表,我只需运行以下命令即可:

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

最后,我将使用此列表并构建结果范围。

var ranges = GetRanges(withoutExcluded);

为此,我创建了一个简单的帮助器Range类和GetRanges方法来分析日期,如果它们是连续的日期,则会建立一个单一范围。

助手Range类:

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 };
}

最终结果如下:

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; }
    }
}
相关问题