While the DateDiff()
function seems like the logical choice for calculating ages, it unfortunately does not calculate the number of full years or months that have elapsed between two dates. For example, say that a baby was born on December 31, 2014, and was examined exactly 48 hours later, on January 2, 2015. That is,
DateOfBirth = DateSerial(2014, 12, 31)
DateOfExam = DateSerial(2015, 1, 2)
If we simply used DateDiff()
to calculate her "age" in years and months at the time of the exam we would get
?DateDiff("yyyy", DateOfBirth, DateOfExam)
1
?DateDiff("m", DateOfBirth, DateOfExam)
1
So, we would report that the baby is 1 year and 1 month old, when really she is just 2 days old.
Proper age calculations need to be more sophisticated than that. The following VBA function will calculate the "age" in years and months, returning a string like "2 years and 1 month":
Public Function AgeInYearsAndMonths(StartDate As Variant, EndDate As Variant) As Variant
Dim Date1 As Date, Date2 As Date
Dim mm1 As Integer, dd1 As Integer, mm2 As Integer, dd2 As Integer
Dim ageYears As Integer, ageMonths As Integer, rtn As Variant
rtn = Null
If Not (IsNull(StartDate) Or IsNull(EndDate)) Then
If StartDate <= EndDate Then
Date1 = StartDate
Date2 = EndDate
Else
Date1 = EndDate
Date2 = StartDate
End If
mm1 = Month(Date1)
dd1 = Day(Date1)
mm2 = Month(Date2)
dd2 = Day(Date2)
ageYears = DateDiff("yyyy", Date1, Date2)
If (mm1 > mm2) Or (mm1 = mm2 And dd1 > dd2) Then
ageYears = ageYears - 1
End If
ageMonths = DateDiff("m", Date1, Date2) Mod 12
If dd1 > dd2 Then
If ageMonths = 0 Then
ageMonths = 12
End If
ageMonths = ageMonths - 1
End If
If ageYears = 0 And ageMonths = 0 Then
rtn = "less than 1 month"
Else
rtn = ageYears & " year" & IIf(ageYears = 1, "", "s") & " and " & ageMonths & " month" & IIf(ageMonths = 1, "", "s")
End If
End If
AgeInYearsAndMonths = rtn
End Function
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…