假设我们有两个日期间隔:
A-------------B
C-------------------------D
在哪里
A
和 C
是开始日期,B
和 D
是日期间隔的结束日期 AB
和 CD
.我发现如果
(B+D)>=(A+C)
我们有日期重叠。但是如果 (B+D)<(A+C)
,我们没有日期重叠。我一直在寻找的东西,但没有成功,它找出了一个通用算法,该算法将日期间隔
AB
的拆分集返回给我.在上述情况下,AB
的分割集将会:A----------(C-1) 'I mean, begining date of interval CD diminished by one day
C----------B 'The actual date overlapping
我不是在寻找一种可以测试所有可能情况的算法,而是一种适用于任何情况的通用算法。
这个算法存在吗?我真的很感激任何帮助!!!
我能弄清楚的所有情况是(但我不确定其他情况):
A---------------B
C--------------------D
A---------------B
C--------------------D
A---------------B
C------D
A------B
C---------------D
A---------------B
C---------------D
A--------B
C--------------D
A--------------B
C---------D
A--------------B
C-------D
A-------B
C--------------D
编辑
根据 Gary's Student 出色的选择答案,我能够找出我需要的功能,如下所示。我不需要知道结果 invervals 的拆分集中的哪一个间隔是重叠的,但是通过函数的一些更改,这很容易完成。
Sub Test()
arr = fSplitOverlap( _
DateSerial(2020, 3, 1), DateSerial(2020, 3, 31), _
DateSerial(2020, 3, 1), DateSerial(2020, 3, 10))
For i = LBound(arr) To UBound(arr) Step 2
Debug.Print arr(i), arr(i + 1)
Next i
End Sub
Function fSplitOverlap(ByVal Di1 As Date, ByVal Df1 As Date, _
ByVal Di2 As Date, ByVal Df2 As Date) As Variant
Dim arr() As Date
Dim DiOver As Date, DfOver As Date
Dim HaveFirsDisjoint1 As Boolean: HaveFirsDisjoint1 = False
DiOver = Application.WorksheetFunction.Max(Di1, Di2)
DfOver = Application.WorksheetFunction.Min(Df1, Df2)
'TEST OVERLAP
If DateDiff("d", DiOver, DfOver) >= 0 Then
'TEST FIRST POSSIBLE DISJOINT INVERVAL
If DateDiff("d", Di1, DateAdd("d", -1, DiOver)) >= 0 Then
ReDim Preserve arr(1 To 4)
arr(1) = Di1
arr(2) = DateAdd("d", -1, DiOver)
arr(3) = DiOver
arr(4) = DfOver
HaveFirsDisjoint1 = True
End If
'TEST SECOND POSSIBLE DISJOINT INVERVAL
If DateDiff("d", DateAdd("d", 1, DfOver), Df1) >= 0 Then
If HaveFirsDisjoint1 = True Then
ReDim Preserve arr(1 To 6)
arr(1) = Di1
arr(2) = DateAdd("d", -1, DiOver)
arr(3) = DiOver
arr(4) = DfOver
arr(5) = DateAdd("d", 1, DfOver)
arr(6) = Df1
Else
ReDim Preserve arr(1 To 4)
arr(1) = DiOver
arr(2) = DfOver
arr(3) = DateAdd("d", 1, DfOver)
arr(4) = Df1
End If
End If
End If
fSplitOverlap = arr
End Function
最佳答案
从您的图片中可以清楚地看出,如果 A>D 或 C>B 那么这些区域是不相交的
否则重叠将是 MIN(B,D) - MAX(A,C) + 1
所以在 VBA 中:
Sub Overlap()
Dim A As Date, B As Date, C As Date, D As Date
A = DateValue("1/11/2020")
B = DateValue("1/20/2020")
C = DateValue("1/15/2020")
D = DateValue("2/13/2020")
If A > D Or C > B Then
MsgBox "no overlap"
Exit Sub
End If
With Application.WorksheetFunction
MsgBox .Min(B, D) - .Max(A, C) + 1
End With
End Sub
这里的重叠是:
关于excel - 日期重叠 : generalized way to split the dates to get the overlapping interval?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60620815/