excel - 日期重叠 : generalized way to split the dates to get the overlapping interval?

标签 excel vba algorithm date data-structures

假设我们有两个日期间隔:

A-------------B
       C-------------------------D

在哪里 AC是开始日期,BD是日期间隔的结束日期 ABCD .

我发现如果 (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

这里的重叠是:
  • 1/15
  • 1/16
  • 1/17
  • 1/18
  • 1/19
  • 1/20
  • 关于excel - 日期重叠 : generalized way to split the dates to get the overlapping interval?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60620815/

    相关文章:

    excel vba-重写从循环中的公式返回的错误(类型不匹配)

    algorithm - Raku 中的简洁(一行?)二分搜索

    c++ - 找到与给定数字相乘的数字的有效方法

    java - 算法编程测试?

    javascript - 将 HTML 表格导出为带有格式的 Excel

    excel - VBA 中的字符串分隔问题

    vba - 在 VBA 中处理过滤集

    excel - Access 中的上限功能

    excel - 在VBA中更改多页选项卡的颜色

    Excel:基于事件日期的日历翻转效果