Language agnostic 日期范围与可为空的日期重叠
我正在寻找这里所问问题的扩展答案: 其中任一日期范围内的任何日期都可以为空。我提出了以下解决方案,但我不确定是否可以进一步简化Language agnostic 日期范围与可为空的日期重叠,language-agnostic,datetime,math,Language Agnostic,Datetime,Math,我正在寻找这里所问问题的扩展答案: 其中任一日期范围内的任何日期都可以为空。我提出了以下解决方案,但我不确定是否可以进一步简化 (StartA == NULL || StartA <= EndB) && (EndA == NULL || EndA >= StartB) && (StartB == NULL || StartB <= EndA) && (EndB == NULL || EndB >= StartA) (St
(StartA == NULL || StartA <= EndB) &&
(EndA == NULL || EndA >= StartB) &&
(StartB == NULL || StartB <= EndA) &&
(EndB == NULL || EndB >= StartA)
(StartA==NULL | | StartA=StartB)&&
(StartB==NULL | | StartB=StartA)
假设:
StartA到EndA和StartB到EndB的日期时间范围
编辑:很抱歉,我很快把上面的逻辑放在了一起,当任何一个范围的开始日期和结束日期都为空时,这似乎失败了。请参阅下面David的解决方案,以获得更好的解释方法。这可能是您能得到的最简单的解决方案,尽管我还没有实际证明它
可能不值得进一步简化,因为在最坏的情况下,该块最终大约是8个操作(由于短路评估,平均为4个)。这种情况可以通过对该问题的稍微概括来处理 让CondA表示日期范围A完全在日期范围B之后(如果StartA>EndB则为True) 让CondB表示日期范围A完全早于日期范围B(如果EndA
CondA
,为了使日期范围A完全在日期范围B之后,日期范围A必须有一个定义的开始时间,日期范围B必须有一个定义的结束时间,并且A的开始时间必须在B的结束时间之后:
CondA := (StartA != null) && (EndB != null) && (StartA > EndB)
CondB
与A和B切换相同:
CondB := (StartB != null) && (EndA != null) && (StartB > EndA)
继续
如果A和B都不为真,则存在重叠
及
现在,我认为德摩根定律是这样说的
不是(A或B)不是A也不是B
重叠==!康达&!康德
== ![(StartA!=null)&&(EndB!=null)&&(StartA>EndB)]&&
![(StartB!=null)&&(EndA!=null)&&(StartB>EndA)]
==[(StartA==null)| |(EndB==null)| | |(StartA如果条件为真,则所有答案均以为基础。我想在此添加一些注释 1-变量类型是一个结构,您不能将其设置为null,除非您使用的是可为null的类型,如“DateTime?” 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;
}
}
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;
}
如果(EndA!=null&&EndB!=null)
{
EndOverLap=EndA
如果不考虑空值,答案是
(StartA=StartB)
(详细说明请参见)
考虑开始日期和结束日期为空,使用C三元运算符语法:
(StartA!=null?StartA:EndB=StartB!=null?StartB:EndA)
或C#4.x样式的空运算符:
(StartA??EndB=StartB??EndA)
或在SQL中:
(合并(开始,结束)谢谢你的详细解释,David!是的,我在发布后很快就意识到我的初始解决方案失败了。这是一个很好的方法,就像deMorgan定律一样,但你不能将第二部分作为编程语句来实现,因为如果startA或EndB中的任何一个都等于null,那么比较运算符将失败。请尽量保持And{&}运算符,因为它在大多数新编译器中都会起短路作用。这在低和编程时都是正确的。![(StartA!=null)&&&&(EndB!=null)&&&(StartA>EndB)&[(StartB!=null)&&(EndA!=null)&(StartB>EndA)]@瓦利德:如果你说的是我的最后两行代码,那当然可以作为一个语句来实现。如果startA
或endB
等于null
,这将被该条件的显式测试捕获,如果startA为null,你将有一个错误,因为compare操作符不能与null。将所有的或门{Logic}转换为and{Logic},然后在开始时将所有的compare转换为null,从而重新组织语句,这样短路和{Logic}就可以工作了。
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)]
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;
}
}