業務アプリケーションでも、予約管理する機能を作成するときがあります。
その時に、予約した日付期間が重複しているかチェックするわけですが、
日付期間の重複チェックを、複雑に記述される方を見られます。
しかし、これには定石のチェック方法があります。
比較開始日付 <= 対象終了日付 AND 比較終了日付 >= 対象開始日付
※条件に、=が成り立っていいかどうかは仕様によります。
Oracleなら「OverLaps oracle」のキーワードで探すといいでしょう。
例では日付にしてますが、Date型を使ってますので時間でも同様です。
'日付が重複するパターンには、以下の4通りがあります。
' |-- 日付 --|
' ① |--------|
' ② |--------|
' ③ |--------|
' ④ |------------|
'対象期間 2008/05/05 ~ 2008/06/15
'期間① 2008/04/01 ~ 2008/05/31
'期間② 2006/05/10 ~ 2006/06/20
'期間③ 2006/06/15 ~ 2006/07/10
'期間④ 2006/05/10 ~ 2006/06/30
'重複しない以下のパターンでは、上の条件式は成立しません。
' |-- 日付 --|
' ① |-----|
' ② |-----|
'対象期間 2008/05/05 ~ 2008/06/15
'期間① 2008/04/01 ~ 2008/05/04
'期間② 2006/06/16 ~ 2006/06/30
Dim dtTable As New DataTable
Dim drRow As DataRow = Nothing
dtTable.Columns.Add("START_DATE", GetType(Date))
dtTable.Columns.Add("END_DATE", GetType(Date))
drRow = dtTable.NewRow()
drRow("START_DATE") = CDate("2008/04/01")
drRow("END_DATE") = CDate("2008/05/31")
dtTable.Rows.Add(drRow)
drRow = dtTable.NewRow()
drRow("START_DATE") = CDate("2008/05/10")
drRow("END_DATE") = CDate("2008/06/20")
dtTable.Rows.Add(drRow)
drRow = dtTable.NewRow()
drRow("START_DATE") = CDate("2008/06/15")
drRow("END_DATE") = CDate("2008/07/10")
dtTable.Rows.Add(drRow)
drRow = dtTable.NewRow()
drRow("START_DATE") = CDate("2008/05/10")
drRow("END_DATE") = CDate("2008/06/30")
dtTable.Rows.Add(drRow)
drRow = dtTable.NewRow()
drRow("START_DATE") = CDate("2008/04/01")
drRow("END_DATE") = CDate("2008/05/04")
dtTable.Rows.Add(drRow)
drRow = dtTable.NewRow()
drRow("START_DATE") = CDate("2008/06/16")
drRow("END_DATE") = CDate("2008/06/30")
dtTable.Rows.Add(drRow)
'重複している場合の抽出条件
'比較開始日付 <= 対象終了日付 AND 比較終了日付 >= 対象開始日付
Dim dv As DataView
dv = dtTable.DefaultView
dv.RowFilter = "START_DATE <= #2008/06/15# AND END_DATE >= #2008/05/05#"
If dv.Count > 0 Then
Console.WriteLine(dv.Count & "件の期間が重複しています。")
End If
'重複していない場合の抽出条件
'比較開始日付 > 対象終了日付 OR 比較終了日付 < 対象開始日付
dv.RowFilter = "START_DATE > #2008/06/15# OR END_DATE < #2008/05/05#"
If dv.Count > 0 Then
Console.WriteLine(dv.Count & "件の期間が重複していません。")
End If