日期范围与可空日期重叠

我正在寻找对此处问题的扩展答案:

确定两个日期范围是否重叠

任何日期范围内的任何日期都可以为空。 我提出了以下解决方案,但我不确定是否可以进一步简化。

(StartA == NULL || StartA <= EndB) &&
(EndA == NULL || EndA >= StartB) &&
(StartB == NULL || StartB <= EndA) &&
(EndB == NULL || EndB >= StartA)

假设:

StartA到EndA和StartB到EndB的DateTime范围

编辑:对不起,我很快把上面的逻辑扔在一起,这似乎失败时,范围的开始和结束日期为NULL。 请参阅下面David的解决方案,以获得更好的解释良好的方法。


这个案子可以通过查尔斯布雷塔那对这个问题的出色答案的略微概括来处理。

令CondA在DateRange B之后完全平均DateRange A(如果StartA> EndB,则为True)设置CondB在DateRange B之前完全平均DateRange A(如果EndA <StartB,则为True)

在这种情况下,假设您希望空日期表示“无开始/结束边界”,则修改条件。 例如,对于CondA ,为使DateRange A完全位于DateRange B之后,DateRange A必须具有定义的开始时间,DateRange B必须具有定义的结束时间,并且A的开始时间必须在B的结束时间之后:

CondA := (StartA != null) && (EndB != null) && (StartA > EndB)

CondB与A和B切换相同:

CondB := (StartB != null) && (EndA != null) && (StartB > EndA)

继续,

那么如果A和B都不是真的,则存在重叠

Overlap := !(CondA || CondB)

现在德摩根的法律,我认为是这样说的

不是(A或B)<=>不是A而不是B

Overlap == !CondA && !CondB
        == ![(StartA != null) && (EndB != null) && (StartA > EndB)] &&
           ![(StartB != null) && (EndA != null) && (StartB > EndA)]
        == [(StartA == null) || (EndB == null) || (StartA <= EndB)] &&
           [(StartB == null) || (EndA == null) || (StartB <= EndA)]

我认为这实际上比您开发的解决方案更强大,因为如果EndB == NULLStartA不为null,则您的第一个条件将比较StartA <= NULL 。 在我熟悉的大多数语言中,这是一个错误条件。


尽管我没有真正证明它,但这可能像你所能得到的那样“简单”。

这可能不值得进一步简化,因为该方案在最坏的情况下最终会进行大约8次操作(平均得益于短路评估4次)。


如果条件为真,所有的答案都是基于此。 我想在这里添加一些注释。

1-日期时间变量类型是一个结构体,除非你使用像“DateTime?”这样的可空类型,否则你不能将它设置为null。

2-要查找重叠范围,请按照以下步骤操作

DateTime? StartOverLap = null,EndOverLap = null;
            if (StartA != null && StartB != null)
            {
                StartOverLap = StartA > StartB ? StartA : StartB;
            }
            else if (StartA == null && StartB != null)
            {
                StartOverLap = StartB;
            }
            else if (StartA != null && StartB == null)
            {
                StartOverLap = StartA;
            }
            if (EndA != null && EndB != null)
            {
                EndOverLap = EndA < EndB ? EndA : EndB;
            }
            else if (EndA == null && EndB != null)
            {
                EndOverLap = EndB;
            }
            else if (EndA != null && EndB == null)
            {
                EndOverLap = EndA;
            }
            if (StartOverLap != null && EndOverLap == null)
            {
                if (EndOverLap < StartOverLap)
                {
                    StartOverLap = null;
                    EndOverLap = null;
                }
            }
链接地址: http://www.djcxy.com/p/54407.html

上一篇: Date Range Overlap with Nullable Dates

下一篇: How to determine if birthday or anniversary occurred during date range