Public Function MonthDiffFloat(ByVal StartDate As Variant, ByVal EndDate As Variant) As Single
'Returns the difference between the two specified dates as a floating-point number of months in which the
'integer part is the whole number of months between the two dates (if any) and the fractional part is the
'difference between the month fraction of the end-date and the month fraction of the start-date. Note that,
'for an end-date month fraction that is greater than the start-date month fraction, there will be a "carry"
'value of 1 added to the whole-month integer part and, for an end-date month fraction that is less than the
'start-date, there will be a "borrow" subtracted from the whole-month integer part, in a manner analogous to
'standard decimal arithmetic.
'
'IMPORTANT: This is a purely mathematical month-fraction calculation that, for both the start-date month
'and the end-month month, depends on the number of days in their respective months. For example, the month
'fraction for the first 15 days of May is 15/31 = 0.484, whereas the fraction for the first 15 days of June
'is 15/30 = 0.500, February 2014 is 15/28 = 0.536, and February 2016 is 15/29 = 0.517.
'
'This subtraction technique can produce results that are counter-intuitive, such as the month-difference
'value between 1/15/2014 and 2/15/2014 is 1.052 (not 1.000) since the difference between the fractional parts
'is .536 - .484 = 0.052.
'
'CAUTION: As a result, this type of month fraction calculation may not be suitable for a particular business
'requirement, such as calculating a particular company's rental car fee or an investment interest value.
Dim MonthDiff As Single
Dim Sign As Integer
If CDate(EndDate) < CDate(StartDate) Then
'End date is earlier than start date, so set the Sign of the result to negative and swap the dates so that
'the (positive) date arithmetic will work correctly.
Sign = -1
Dim Temp As Variant
Temp = StartDate: StartDate = EndDate: EndDate = Temp
Else
'End date is equal to or later than start date, so set the Sign of the result to positive.
Sign = 1 '+1
End If
'Note that a date range that spans the new-year is not a special case due to the normal borrow/carry effect
'described in the function-description paragraph, above.
MonthDiff = (Month(EndDate) + Day(EndDate) / DaysInMonth(EndDate)) - _
(Month(StartDate) + Day(StartDate) / DaysInMonth(StartDate))
MonthDiffFloat = Sign * (12 * (Year(EndDate) - Year(StartDate)) + MonthDiff)
End Function
Function DaysInMonth(Dateval As Variant) As Integer
DaysInMonth = Day(DateDiff("d", 1, DateSerial(Year(Dateval), Month(Dateval) + 1, 1)))
End Function