【问题标题】:How should I find missing datetime in datetime range我应该如何在日期时间范围内找到丢失的日期时间
【发布时间】:2018-08-22 15:35:28
【问题描述】:

我是 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# 专家指导我应该如何实现它。我不是要代码,但也许如果有人写了类似的逻辑,那么请分享这个想法或提供任何参考。

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

【问题讨论】:

  • 我可能会使用Tuple 来做你想做的事情。您似乎正在寻找的逻辑是简单地从所述月份的第一个日期开始,然后遍历列表“次要日期范围”并检查开始日期。 if 每月的第一天不等于“次要日期范围”中的第一个元素,您的第一个元素是 STARTDATE,您可以继续循环查找第一个的 ENDDATE差距。冲洗并重复直到月底。
  • 我认为您示例中结果中的范围不正确:2018-06-18 2018-06-19

标签: c#


【解决方案1】:

你可以使用 Linq,除了FilteredList = BiggerList.Except(SmallerList).ToList()

【讨论】:

  • 不确定,范围不是单个元组或单元格。 STARTDATE 和 ENDDATE 是不同的列或字段,你可以说。
【解决方案2】:

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

https://dotnetfiddle.net/2fv8bY

【讨论】:

    【解决方案3】:

    我借鉴了 PiJei 的建议。然后使用方法扩展它以获取起始范围内的天数,并使用一种方法来构建日期的最终范围。

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

    为此,我使用了从 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; }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-18
      • 2015-04-10
      • 1970-01-01
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多