我有一系列句点[FromDate, ToDate]
。
我想知道给定时期与集合中的时期之间是否有任何重叠。
我已经开始这样做了:
// periodToCheck is the given item
bool conflict = Periods.Any(p => ((p.FromDate >= periodToCheck.fromDate &&
p.FromDate <= periodToCheck.toDate)
||
(p.ToDate >= periodToCheck.fromDate &&
p.ToDate <= periodToCheck.toDate))
);
它没有涵盖所有情况的问题,例如:
[2010.1.1], [2010.1.31]
[2010.1.5], [2010.1.6] // Is valid in the query in spite of it is not valid
// (because there is intersection).
如果我讨论更多情况,我认为查询会变得更复杂。
我想知道你是否可以用最简单的有效方法帮助我。
问候。
答案 0 :(得分:7)
相反地采用这种方式:如果检查日期的条件是&lt;从日期开始,或检查日期是从日期&gt;到目前为止。这是假设check.from&lt; = check.to。
Periods.Any(p => !(check.ToDate < p.FromDate || check.FromDate > p.ToDate));
或(在解开否定之后):
Periods.Any(p => check.ToDate >= p.FromDate && check.FromDate <= p.ToDate));
答案 1 :(得分:6)
如果FromDate <= ToDate
对象的Period
始终成立,您可以按如下方式定义帮助extension method OverlapsWith
:
public static bool OverlapsWith(this Period a, Period b)
{
return !(b.ToDate <= a.FromDate || a.ToDate <= b.FromDate);
}
为了说明正在发生的事情,让我们看看a
和b
之间没有重叠的两种情况:
// a
// |-----------------|
// |--------| |-----------|
// b1 b2
您可以根据此图表检查上述条件。由于该图显示了不发生重叠的情况,但该方法确实应该测试的重叠,因此需要否定该条件。它可以简化为以下内容:
b.ToDate > a.FromDate && a.ToDate > b.FromDate
在LINQ查询中使用此方法时,很容易理解:
Periods.Any(period => period.OverlapsWith(periodToCheck))
答案 2 :(得分:1)
您可能会发现following article有用,特别是TimePeriodIntersector
类。
示例摘录:
public void TimePeriodIntersectorSample()
{
TimePeriodCollection periods = new TimePeriodCollection();
periods.Add( new TimeRange( new DateTime( 2011, 3, 01 ), new DateTime( 2011, 3, 10 ) ) );
periods.Add( new TimeRange( new DateTime( 2011, 3, 05 ), new DateTime( 2011, 3, 15 ) ) );
periods.Add( new TimeRange( new DateTime( 2011, 3, 12 ), new DateTime( 2011, 3, 18 ) ) );
periods.Add( new TimeRange( new DateTime( 2011, 3, 20 ), new DateTime( 2011, 3, 24 ) ) );
periods.Add( new TimeRange( new DateTime( 2011, 3, 22 ), new DateTime( 2011, 3, 28 ) ) );
periods.Add( new TimeRange( new DateTime( 2011, 3, 24 ), new DateTime( 2011, 3, 26 ) ) );
TimePeriodIntersector<TimeRange> periodIntersector =
new TimePeriodIntersector<TimeRange>();
ITimePeriodCollection intersectedPeriods = periodIntersector.IntersectPeriods( periods );
foreach ( ITimePeriod intersectedPeriod in intersectedPeriods )
{
Console.WriteLine( "Intersected Period: " + intersectedPeriod );
}
// > Intersected Period: 05.03.2011 - 10.03.2011 | 5.00:00
// > Intersected Period: 12.03.2011 - 15.03.2011 | 3.00:00
// > Intersected Period: 22.03.2011 - 26.03.2011 | 4.00:00
} // TimePeriodIntersectorSample
答案 3 :(得分:0)
2个具有共同日期的期间,例如期间1的ToDate和期间2的FromDate是相同的,计算在交叉点?
如果是,那么对您的查询进行一点修改,只需检查一个句点的日期,如果它们在一个检查周期内,就好像其中一个日期属于一个句点,那么就有交集:
bool conflict = Periods.Any(p => ((p.FromDate >= periodToCheck.fromDate &&
p.ToDate <= periodToCheck.fromDate)
||
(p.FromDate >= periodToCheck.toDate &&
p.ToDate <= periodToCheck.toDate))
);