【问题标题】:Given a list of Date ranges, how I do verify that all the days in a date range are covered in the list?给定日期范围列表,我如何验证日期范围内的所有日期是否都包含在列表中?
【发布时间】:2013-01-07 20:36:55
【问题描述】:

我有一个日期范围列表。

05/01/2012 - 07/01/2012
07/02/2012 - 09/05/2012
01/01/2012 - 03/31/2012
08/01/2012 - 12/31/2012

现在的问题是验证给定列表是否涵盖特定范围内的所有日期。例如,此列表涵盖 05/01/2012 - 12/31/2012 范围内的所有日期,但非 01/01/2012-12/31/2012,因为此列表未涵盖四月日期。假设是,

  1. 日期范围有效 - 开始日期
  2. 日期范围可能会重叠,如上述 2 日和 4 日的情况。
  3. 列表未以任何方式排序。

到目前为止,我所做的是测试异常值,例如,

找出最小的开始日期和最大的结束日期 - 如果您的测试日期范围的开始日期和/或结束日期分别小于/大于这些日期,则测试失败。

但是,在中间检查任何错过的日期的最佳策略是什么?提前致谢!

【问题讨论】:

  • 闻起来像逻辑问题..
  • "正确 - 开始日期总是
  • 你约会的基本对象是什么? java.util.Date?
  • 另外,您只是在寻找日精度吗?有代码吗?
  • 日期范围可以有多大?您可以创建一个位向量并开始在范围内打勾日期。完成后,您应该有一个连续的 1 块。我的猜测是对范围进行排序,然后比较 end 和 start 会非常有效。

标签: c# java date


【解决方案1】:

最简单的策略是解析所有涉及的日期。 O(N)

按开始日期对日期进行排序。 O(N log N)时间

比较结束日期​​和下一个开始日期(忽略任何倒退的结束日期)O(N)

如果到下一个开始日期的一端超过一天,则表示有间隔。

【讨论】:

  • 如果你使用 Joda Time,实际上有一个更好的方法:从第一个元素获取开始日期,检查每个元素的 interval.endDate().plusDays(1) 是否等于下一个元素的开始日期。也就是说,如果 OP 想要日精度。
  • @Peter Lawrey - 感谢您的回答。我认为最后一步有一个小问题。如果我在给定范围内测试 05/01/2012-12/31/2012 范围内的所有日子,它应该通过,但你的最后一步说有一个不正确的差距。我想我需要在你的最后一步之前完成@Guvante 描述的步骤。
【解决方案2】:

首先要做的是修复你的输入数据。

  1. 按开始日期对所有范围进行排序
  2. 通过设置开始日期删除所有重叠
  3. 消除任何因 2 而消失的范围

所以你的范围会变成

01/01/2012 - 03/31/2012
05/01/2012 - 07/01/2012
07/02/2012 - 09/05/2012
09/06/2012 - 12/31/2012

然后你只需要找到丢失的日期,看看你是否能弄清楚如何做到这一点。

【讨论】:

  • 谢谢。我会尝试你的步骤4)。找到测试范围的起点和终点。 5)。看看两者之间是否缺少任何日期。例如,如果测试范围是 05/02-05/15,那么起点和终点是 2 - 没有间隙。如果测试范围是 03/15 到 06/01,起点是 1,终点是 2。1 的结束日期和 2 的开始日期之间有 30 天的间隔 - 所以测试失败。现在我必须将其转换为代码。
【解决方案3】:

将日期转换为自 1970 年 1 月 1 日(或其他参考日期)以来的天数。

那么你的问题就变成了寻找缺失的整数。

【讨论】:

  • 这取决于搜索的粒度...我不认为 OP 想要毫秒精度。
【解决方案4】:

生成范围内的每个日期,将它们放在一个列表中并测试以查看您的候选人是否在该列表中。

【讨论】:

    【解决方案5】:

    尝试以下操作(按最小日期对列表范围进行排序后):-

      i=0
      a=min_date at 0 position
    b=max_date corresponding to a
    
    while list has elements
       c= min_date at (i+1) position
       d=max_date corresponding to c
    
    if (b< (c - 1 day))
    then there is a gap;
    else 
    { 
    if(b<d)   // done to handle the situation :- 06/07/2012 - 12/31/2012
              // 08/07/2012 - 11/31/2012. Then b will still remain 12/31/2012 after if condition
    {
      b=d;
    }
    }
    i=i+2;
    end while;
    

    以上只会在列表中找到任何缺失的日期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多