简体   繁体   中英

Excel VBA datediff to Calculate Months, Days and Month together?

I'm trying to calculate the time elapsed with the total amount of months, Days and Hours together using Datediff function. Is it not possible?

DateDiff("d hh", datein, Now)

What can I do?

That's not possible as the interval parameter can only be a single string.

You will have to do a bit more work like get the difference in hours and if it's above 24 convert the part before decimal separator into days

Sub Main()

    Dim d1 As Date
    d1 = "15/10/2014 08:00:03"

    Dim d2 As Date
    d2 = Now

    Dim hrsDiff As Long
    hrsDiff = DateDiff("h", d1, d2)

    MsgBox IIf(hrsDiff >= 24, _
               hrsDiff \ 24 & " days " & hrsDiff Mod 24 & " hours", _
               hrsDiff & " hours")

End Sub

This is rough and ready, but is just directional. You could make a user defined function. This one returns 1:2:22:15 as a string (but you could return a custom class instance with variables for months, days, hours, minutes). It doesn't account for date2 being before date1 (not sure what happens then), nor does it account for date1 only being a partial day (assumes date1 is midnight).

Function MyDateDiff(date1 As Date, date2 As Date) As String
    Dim intMonths As Integer
    Dim datStartOfLastMonth As Date
    Dim datStartOfLastHour As Date
    Dim datEndOfMonth As Date
    Dim intDays As Integer
    Dim intHours As Integer
    Dim intMinutes As Integer
    Dim strResult As String
    ' Strip of any time
    datStartOfLastMonth = DateSerial(Year(date2), Month(date2), Day(date2))

    ' check the dates arent in the same month
    If Not ((Month(date1) = Month(date2) And Year(date1) = Year(date2))) Then

        ' how many months are there
        intMonths = DateDiff("m", date1, date2)
        Debug.Print (intMonths)

        ' how many days difference are there
        intDays = DateDiff("d", DateAdd("m", intMonths, date1), date2)
        Debug.Print (intDays)

        ' how many hours difference are there
        intHours = DateDiff("h", datStartOfLastMonth, date2)
        Debug.Print (intHours)

        ' how many minutes different are there
        datStartOfLastHour = datStartOfLastMonth + (DatePart("h", date2) / 24)
        intMinutes = DateDiff("n", datStartOfLastHour, date2)
        Debug.Print (intMinutes)
    Else
        ' Dates are in the same month
        intMonths = 0
        Debug.Print (intMonths)

        ' how many days difference are there
        intDays = DateDiff("d", date1, date2)
        Debug.Print (intDays)

        ' how many hours difference are there
        intHours = DateDiff("h", datStartOfLastMonth, date2)
        Debug.Print (intHours)

        ' how many minutes different are there
        datStartOfLastHour = datStartOfLastMonth + (DatePart("h", date2) / 24)
        intMinutes = DateDiff("n", datStartOfLastHour, date2)
        Debug.Print (intMinutes)
    End If

     strResult = intMonths & ":" & intDays & ":" & intHours & ":" & intMinutes
     MyDateDiff = strResult
End Function

Testing this:

?MyDateDiff("01-SEP-2014", "03-Oct-2014 22:15:33")

Gives:

1:2:22:15

ie 1 month, 2 days, 22 minutes and 15 seconds.

Reverse testing this by adding the components back onto date1 gives:

?DateAdd("n",15,DateAdd("h",22,DateAdd("d",2,DateAdd("m",1,"01-SEP-2014"))))

= "03-Oct-2014 22:15:33"

If we try with 2 dates in the same month:

?MyDateDiff("01-SEP-2014", "03-SEP-2014 22:15:33")

We get:

0:2:22:15

Reverse testing this:

?DateAdd("n",15,DateAdd("h",22,DateAdd("d",2,DateAdd("m",0,"01-SEP-2014"))))

Gives:

03/09/2014 22:15:00

But you may want to account for dates being the wrong way round...and you may only want date1 to be counted as a partial date if it starts later in the day....as I say, just a thought.

Regards

i

This may give you some ideas to correct for days in month or leap year Feb

Private Sub CommandButton1_Click()
    DoDateA
End Sub

Sub DoDateA()
    Dim D1 As Date, D2 As Date, DC As Date, DS As Date
    Dim CA: CA = Array("", "yyyy", "m", "d", "h", "n", "s", "s")
    Dim Va%(7), Da(7) As Date, Ci%
    D1 = Now + Rnd() * 420  ' vary the  * factors for range of dates
    D2 = Now + Rnd() * 156
    If D1 > D2 Then
        [b4] = "Larger"
    Else
        [b4] = " smaller"
        DS = D1
        D1 = D2
        D2 = DS
    End If
    [d4] = D1
    [e4] = D2
    DC = D2
    For Ci = 1 To 6
        Va(Ci) = DateDiff(CA(Ci), DC, D1)
        DC = DateAdd(CA(Ci), Va(Ci), DC)
        Va(Ci + 1) = DateDiff(CA(Ci + 1), DC, D1)
        If Va(Ci + 1) < 0 Then  ' added too much
            Va(Ci) = Va(Ci) - 1
            DC = DateAdd(CA(Ci), -1, DC)
            Cells(9, Ci + 3) = Va(Ci + 1)
            Cells(8, Ci + 3) = Format(DC, "yyyy:mm:dd hh:mm:ss")
        End If
        Da(Ci) = DC
        Cells(5, Ci + 3) = CA(Ci)
        Cells(6, Ci + 3) = Va(Ci)
        Cells(7, Ci + 3) = Format(Da(Ci), "yyyy:mm:dd hh:mm:ss")
        Cells(10, Ci + 3) = DateDiff(CA(Ci), D2, D1)
    Next Ci
End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM