2 つの日付範囲がある場合、2 つの日付範囲が重複しているかどうかを判断する最も簡単または効率的な方法は何ですか?
たとえば、DateTime 変数からStartDate1
およびEndDate1
から StartDate2
までの範囲があるとしますEndDate2
。
ベストアンサー1
(StartA <= EndB) かつ (EndA >= StartB)
証明:
条件Aは、日付範囲Aが日付範囲Bより完全に後であることを意味するものとする
_ |---- DateRange A ------|
|---Date Range B -----| _
(次の場合は真StartA > EndB
)
条件Bは日付範囲Aが日付範囲Bより完全に前であることを意味します
|---- DateRange A -----| _
_ |---Date Range B ----|
(次の場合は真EndA < StartB
)
A と B のどちらも当てはまらない場合は重複が存在します
(一方の範囲が他方の範囲より完全に後でも、
他方の範囲より完全に前でもない場合は、重複している必要があります)。
今、ド・モルガンの法則次のように述べています。
Not (A Or B)
<=>Not A And Not B
翻訳すると次のようになります:(StartA <= EndB) and (EndA >= StartB)
注意: これには、エッジが完全に重なる条件も含まれます。これを除外したい場合は、演算子を、 、に
変更します。>=
>
<=
<
注2. @Baodadに感謝します。このブログ実際の重複は、{、、、}
のendA-startA
うち最小になりますendA - startB
。endB-startA
endB - startB
(StartA <= EndB) and (EndA >= StartB)
(StartA <= EndB) and (StartB <= EndA)
注 3。@tomosius のおかげで、短縮版は次のようになりました:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
これは実際には、開始日が終了日以前であることを確認するための追加のチェックを含む、より長い実装の構文上のショートカットです。上記からこれを導き出します:
開始日と終了日の順序が間違っている可能性がある場合、つまり、またはの可能性がある場合にはstartA > endA
、startB > endB
それらが正しい順序であるかどうかも確認する必要があります。つまり、次の 2 つの妥当性ルールを追加する必要があります。
(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)
または:
(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)
または、
(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))
または:
(Max(StartA, StartB) <= Min(EndA, EndB)
しかし、Min()
とを実装するにはMax()
、次のようにコーディングする必要があります (簡潔にするために C の三項演算子を使用)。
((StartA > StartB) ? StartA : StartB) <= ((EndA < EndB) ? EndA : EndB)