title: Computing & Evaluating Negative Time Values in VBA
body: <p>I am new to VBA and have encountered an issue.<br>
  My objective is to find an elegant way of evaluating negative time values.</p>
  
  <p>For example, the body of code below generates a message box which displays <code>12:30:00 AM</code>. I would expect it to display <code>11:30:00 PM</code>.  </p>
  
  <pre><code>Sub Main() 'Run Test
  Dim difference As Date
      difference = #12:00:00 AM# - #12:30:00 AM#
      MsgBox difference
  End Sub 
  </code></pre>
  
  <p>I have created a solution to this issue, but would like to know the coding community's feedback.<br>
  Some of the code is not necessary, but I have written it for functionality that may be important in the future.</p>
  
  <p>The <code>run</code> sub routine allows you to run the <code>test</code> function with your specified values.<br>
  The <code>test</code> function tests the <code>timeDiff</code> &amp; <code>timeSum</code> logic.<br>
  The <code>timeDiff</code> function finds the time-difference between <code>t1</code> and <code>t0</code>.<br>
  The <code>timeSum</code> function finds the time-sum of <code>t1</code> and <code>t0</code>.<br>
  The <code>asDuration</code> function removes the AM/PM suffix from a time value.<br>
  The <code>asMilitary</code> function converts 12-hour format to 24 hour-format.<br>
  The <code>concat</code> function I created to more easily concatenate strings.</p>
  
  <pre><code>Sub Main() 'Run Test
      MsgBox Test("0:29:0", "23:30:0")
  End Sub
  
  
  Function Test(startT As Date, endT As Date) 'Test timeDiff &amp; timeSum logic
      Dim nextShift As Date, prevShift As Date, hours As Date
  
      hours = timeDiff(endT, startT)
      prevShift = timeDiff(startT, "0:30:0")
      nextShift = timeSum("0:30:0", endT)        
  
      Test = concat("Start -", startT, "", "End - ", endT, "", "Duration -", asDuration(hours), "", "Next Shift: ", nextShift, "", "Prev Shift: ", prevShift)
  End Function
  
  
  Function timeDiff(t1 As Date, t0 As Date) As Date 'Return Time1 minus Time0
      Dim units(0 To 2) As String
  
      units(0) = Hour(t1) - Hour(t0)
      units(1) = Minute(t1) - Minute(t0)
      units(2) = Second(t1) - Second(t0)
  
      If units(2) &lt; 0 Then
          units(2) = units(2) + 60
          units(1) = units(1) - 1
      End If
  
      If units(1) &lt; 0 Then
          units(1) = units(1) + 60
          units(0) = units(0) - 1
      End If
  
      units(0) = IIf(units(0) &lt; 0, units(0) + 24, units(0))
      timeDiff = Join(units, ":")
  End Function
  
  
  Function timeSum(t1 As Date, t0 As Date) As Date 'Return Time1 plus Time0
      Dim units(0 To 2) As String
  
      units(0) = Hour(t1) + Hour(t0)
      units(1) = Minute(t1) + Minute(t0)
      units(2) = Second(t1) + Second(t0)
  
      If units(2) &gt;= 60 Then
          units(2) = units(2) Mod 60
          units(1) = units(1) + 1
      End If
  
      If units(1) &gt;= 60 Then
          units(1) = units(1) Mod 60
          units(0) = units(0) + 1
      End If
  
      units(0) = IIf(units(0) &gt;= 24, units(0) Mod 24, units(0))
      timeSum = Join(units, ":")
  End Function
  
  
  Function asDuration(time As Date) As String 'Display as duration; Remove AM/PM suffix from time
      time = asMilitary(time)
      asDuration = Left(time, Len(time))
  End Function
  
  
  Function asMilitary(time As Date) As String 'Convert 12-hour format to 24-hour-format
      asMilitary = Hour(time) &amp; ":" &amp; Minute(time) &amp; ":" &amp; Second(time)
  End Function
  
  
  Function concat(ParamArray var() As Variant) As String 'Return arguments of function call concatenated as a single string
      For Each elem In var()
          concat = IIf(elem &lt;&gt; "", concat &amp; elem &amp; " ", concat &amp; vbNewLine)
      Next
  End Function
  </code></pre>