在 Microsoft Access (2010) 中计算年龄(以年和月为单位)
calculating age in years and months in Microsoft Access (2010)
我有两个字段(体检日期和出生日期)。我计算了年龄((体检日期-出生日期)/365.25)。我想要做的是在单独的字段中计算年和月的年龄。我不确定是否可以使用代码生成器或某种方式完成。
需要更多的时间来处理更精细的细节(一年的计算也是如此):
Public Function Months( _
ByVal datDate1 As Date, _
ByVal datDate2 As Date, _
Optional ByVal booLinear As Boolean) _
As Integer
' Returns the difference in full months between datDate1 and datDate2.
'
' Calculates correctly for:
' negative differences
' leap years
' dates of 29. February
' date/time values with embedded time values
' negative date/time values (prior to 1899-12-29)
'
' Optionally returns negative counts rounded down to provide a
' linear sequence of month counts.
' For a given datDate1, if datDate2 is decreased stepwise one month from
' returning a positive count to returning a negative count, one or two
' occurrences of count zero will be returned.
' If booLinear is False, the sequence will be:
' 3, 2, 1, 0, 0, -1, -2
' If booLinear is True, the sequence will be:
' 3, 2, 1, 0, -1, -2, -3
'
' If booLinear is False, reversing datDate1 and datDate2 will return
' results of same absolute Value, only the sign will change.
' This behaviour mimics that of Fix().
' If booLinear is True, reversing datDate1 and datDate2 will return
' results where the negative count is offset by -1.
' This behaviour mimics that of Int().
' DateAdd() is used for check for month end of February as it correctly
' returns Feb. 28. when adding a count of months to dates of Feb. 29.
' when the resulting year is a common year.
'
' 2010-03-30. Cactus Data ApS, CPH.
Dim intDiff As Integer
Dim intSign As Integer
Dim intMonths As Integer
' Find difference in calendar months.
intMonths = DateDiff("m", datDate1, datDate2)
' For positive resp. negative intervals, check if the second date
' falls before, on, or after the crossing date for a 1 month period
' while at the same time correcting for February 29. of leap years.
If DateDiff("d", datDate1, datDate2) > 0 Then
intSign = Sgn(DateDiff("d", DateAdd("m", intMonths, datDate1), datDate2))
intDiff = Abs(intSign < 0)
Else
intSign = Sgn(DateDiff("d", DateAdd("m", -intMonths, datDate2), datDate1))
If intSign <> 0 Then
' Offset negative count of months to continuous sequence if requested.
intDiff = Abs(booLinear)
End If
intDiff = intDiff - Abs(intSign < 0)
End If
' Return count of months as count of full 1 month periods.
Months = intMonths - intDiff
End Function
虽然 DateDiff()
函数似乎是计算年龄的合理选择,但遗憾的是它无法计算两个日期之间经过的 整 年或月数.例如,假设婴儿出生于2014年12月31日,正好在48小时后,即2015年1月2日进行检查。即
DateOfBirth = DateSerial(2014, 12, 31)
DateOfExam = DateSerial(2015, 1, 2)
如果我们简单地使用 DateDiff()
来计算她 "age" 在考试时的年数和月数,我们将得到
?DateDiff("yyyy", DateOfBirth, DateOfExam)
1
?DateDiff("m", DateOfBirth, DateOfExam)
1
所以,我们会报告婴儿 1 岁 1 个月大,而实际上她只有 2 天 大。
正确的年龄计算需要比这更复杂。以下 VBA 函数将计算 "age" 年和月,返回类似“2 年零 1 个月”的字符串:
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
我有两个字段(体检日期和出生日期)。我计算了年龄((体检日期-出生日期)/365.25)。我想要做的是在单独的字段中计算年和月的年龄。我不确定是否可以使用代码生成器或某种方式完成。
需要更多的时间来处理更精细的细节(一年的计算也是如此):
Public Function Months( _
ByVal datDate1 As Date, _
ByVal datDate2 As Date, _
Optional ByVal booLinear As Boolean) _
As Integer
' Returns the difference in full months between datDate1 and datDate2.
'
' Calculates correctly for:
' negative differences
' leap years
' dates of 29. February
' date/time values with embedded time values
' negative date/time values (prior to 1899-12-29)
'
' Optionally returns negative counts rounded down to provide a
' linear sequence of month counts.
' For a given datDate1, if datDate2 is decreased stepwise one month from
' returning a positive count to returning a negative count, one or two
' occurrences of count zero will be returned.
' If booLinear is False, the sequence will be:
' 3, 2, 1, 0, 0, -1, -2
' If booLinear is True, the sequence will be:
' 3, 2, 1, 0, -1, -2, -3
'
' If booLinear is False, reversing datDate1 and datDate2 will return
' results of same absolute Value, only the sign will change.
' This behaviour mimics that of Fix().
' If booLinear is True, reversing datDate1 and datDate2 will return
' results where the negative count is offset by -1.
' This behaviour mimics that of Int().
' DateAdd() is used for check for month end of February as it correctly
' returns Feb. 28. when adding a count of months to dates of Feb. 29.
' when the resulting year is a common year.
'
' 2010-03-30. Cactus Data ApS, CPH.
Dim intDiff As Integer
Dim intSign As Integer
Dim intMonths As Integer
' Find difference in calendar months.
intMonths = DateDiff("m", datDate1, datDate2)
' For positive resp. negative intervals, check if the second date
' falls before, on, or after the crossing date for a 1 month period
' while at the same time correcting for February 29. of leap years.
If DateDiff("d", datDate1, datDate2) > 0 Then
intSign = Sgn(DateDiff("d", DateAdd("m", intMonths, datDate1), datDate2))
intDiff = Abs(intSign < 0)
Else
intSign = Sgn(DateDiff("d", DateAdd("m", -intMonths, datDate2), datDate1))
If intSign <> 0 Then
' Offset negative count of months to continuous sequence if requested.
intDiff = Abs(booLinear)
End If
intDiff = intDiff - Abs(intSign < 0)
End If
' Return count of months as count of full 1 month periods.
Months = intMonths - intDiff
End Function
虽然 DateDiff()
函数似乎是计算年龄的合理选择,但遗憾的是它无法计算两个日期之间经过的 整 年或月数.例如,假设婴儿出生于2014年12月31日,正好在48小时后,即2015年1月2日进行检查。即
DateOfBirth = DateSerial(2014, 12, 31)
DateOfExam = DateSerial(2015, 1, 2)
如果我们简单地使用 DateDiff()
来计算她 "age" 在考试时的年数和月数,我们将得到
?DateDiff("yyyy", DateOfBirth, DateOfExam)
1
?DateDiff("m", DateOfBirth, DateOfExam)
1
所以,我们会报告婴儿 1 岁 1 个月大,而实际上她只有 2 天 大。
正确的年龄计算需要比这更复杂。以下 VBA 函数将计算 "age" 年和月,返回类似“2 年零 1 个月”的字符串:
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