We help IT Professionals succeed at work.

Subtract Time from Time to get time difference

wilsoada used Ask the Experts™
dim sendtime as string
dim receivedtime as string

sendTime = Time
'function call
receiveTime = Time

I want to get the minutes and seconds that it took to perfrom the function call and be able to save the result. Eventually there would be lots of these time differences saved and I'd like to sum them all up and find the average time it is taking to complete this function call.

I ust get gibberish from everything I try. Lots of points hope someone is out there!
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2006


your problem is that you are using strings to store the time not dates.  This should resolve the error.

Normally I would do this with the timer object for this.  It is generally more precise


Dim startTime as double
Dim endTime as double

startTime = timer
'do code
endTime = timer

msgbox "Your Function Took:- " & (endtime- starttime) & " Seconds"
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

You can also do:

Private startTime As Date
Private stopTime As Date
Private elapsed As Date

Private Sub cmdStart_Click()
    startTime = Now
    txtStartTime.Text = Format(startTime, "hh:mm:ss am/pm")
End Sub

Private Sub cmdStop_Click()
    stopTime = Now
    txtStopTime.Text = Format(stopTime, "hh:mm:ss am/pm")
    elapsed = stopTime - startTime
    txtElapsedTime.Text = Format(elapsed, "hh:mm:ss")
End Sub
jkaiosIT Director

This one uses the DateDiff() function to calculate the duration (time elapsed in seconds)
and then returns the result in hours, minutes, and seconds.

 Dim vStarts
 Dim vFinish
 Dim vTotal

 vStarts = Now()
 ' some function call
 vFinish = Now()

 vTotal = DateDiff("s", vStarts, vFinish)

 MsgBox "Duration: " & Fix(vTotal / 60 / 60) & " hrs, " & _
                                  Fix(vTotal / 60) Mod 60 & " min, " & _
                                  vTotal Mod 60 & " sec")

When you subtrat two times the result is a double which is the fraction of a day. e.g. 0.5 would be 12 hours

Public Sub Test()

    Dim startTime As Double
    Dim endTime As Double
    startTime = Now()
    'do code
    Debug.Assert True
    endTime = Now()

    ShowTime (CDbl(endTime - startTime))

End Sub
Private Sub ShowTime(dTimeTaken As Double)

    Dim iDays As Long
    Dim iHours As Long
    Dim iMinutes As Long
    Dim iSeconds As Long
    Dim dFractionOfASecond As Double
    Dim iThousandthsOfASecond As Double
    iDays = Fix(dtimetake)
    iHours = Fix((dTimeTaken - iDays) * 24)
    iMinutes = Fix((dTimeTaken - (CDbl(iHours) / 24)) * 60 * 24)
    iSeconds = Fix((dTimeTaken - iHours / 24 - (iMinutes / (24 * 60))) * 60 * 60 * 24)
    MsgBox "Time taken" & iDays & " days" & vbNewLine & _
            iHours & " Hours" & vbNewLine & _
            iMinutes & " Minutes" & vbNewLine & _
            iSeconds & " Seconds"

End Sub
JRCSystemsDirector of Application Development

I will add my 2 cents-worth here. All stuff above seems correct.

There is however a nasty gotcha that I ran into dealing with Date/Time in a timecard system written in VB.
Because of the internal representation of "Date" data types, where 0.5 = 12pm, 0.75 = 6pm, etc...
it IS VERY possible that you could have 2 variables of date type, that if printed or displayed on screen in the usual format BOTH might look like "11/21/2006 09:33 pm", yet IF compared to one another, may not be equal.

Here is the Exact comment I left in the code, which speaks all for itself:

'   GOD knows why... but for certain dates/times, it is far better off converting the
'       date/time to a STRING, then compare the strings. During testing, when comparing
'       two times, VB said that "5:23:00 PM" was NOT EQUAL to "5:23:00 PM". BOTH fields
'       were defined as DATES. Curious, I did a PRINT DATE1-DATE2 ==> 1.11022302462516E-16
'       which is some damn # so damn small it is rediculous! Hence, compare times in STRINGS

^ "GOD knows why..."  and so do I:

The Date type is basically a Double value which is a floating point value.  In computers, there is only a limited precision with floating point values--i.e., once you get a certain number of places to the right of the decimal point, computers need to start rounding stuff off.

If you consider that in a Date value, the date is the integer portion, and the time is the decimal portion, and that the decimal portion is represented by the percentage of minutes of the day that have elapsed, it's easy to understand that for some time values you're going to have these rounding errors.

In your example, 0.5 is 12pm.  But 0.5000000001 is also rounded off to 12pm when displaying the time as a string.  So if one of your Date variables contains 0.5 precisely, and another contains 0.500000001, then when you compare the two Date values they are NOT equal, while if you convert them to String they ARE.

That's why I think comparing dates using the DateDiff function is preferable, because they take this precision issue into account.

I forgot to add this note:  If this program is ever going to be running through midnight, using the Timer method will become a problem, because the Timer function returns a Single value representing the number of seconds elapsed since midnight.  So, if you were to start the process at 11:59PM, and then stop it at 12:01AM, then subtract the start time from the stop time, you'll end up with a huge negative number, instead of 120 seconds like you wanted.  This, again, is another reason to use the DateDiff function.
1) You should always use numerics when working with Date or Time becuase it is way faster.

Also automatically handles midnigh problems.

Dim dtStart As Date
Dim dtEnd As Date

dtStart = Now
' Call Function
dtEnd = Now

MsgBox "Time Taken: " + Format(dtEnd-dtStart, "HHH:NN:SS") ' shows hours mins seconds

2) The is a special function which will do this more accurately for very fast functiuon calls use GetTickCoung. To make this easy to use I put into a class module which I decalare globally. The function returns Milliseconds.

Global GF As New zGF

In your sub:

Dim lStart As Long
Dim lEnd As Long

lStart = GF.GetTickCounter()
' Call Function
lEnd As Long

MsgBox "The function took: " +Format((lEnd - lStart)*.001, "0.000")+" Seconds"

Here is an extract form the class general functions (zGF)

Optional Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Function GetTickCounter() As Long
GetTickCounter = GetTickCount
End Function

Woops rushing too much

lStart = GF.GetTickCounter
' Call Function
lEnd = GF.GetTickCounter


Sorry forgot I had this open inthedark great this worked perfectly