Stop the Rounding madness!!!!

Dylan Ross

Registered User.
Local time
Today, 20:51
Joined
Jul 24, 2003
Messages
13
:eek:

I have the following formula in a query, and am trying to get it to stop rounding up. I am trying to determine someone's age as of 7/1/08 with this formula Age Band: ((#7/1/2008#-[Date of Birth])/365), but I can't seem to get any formula to work.

Example: If someone's age calculates to 21.36, I want it to be 21. Similiarly, if their age is 21.95, I still want it to be 21.

I'm going to need to purchase a good single malt scotch if I don't get this resolved!

Thanks in advance,

DR
 
Try this

If Month(DateToday) < Month(Bdate) Or (Month(DateToday) = Month(Bdate) And Day(DateToday) < Day(Bdate)) Then
Age = Year(DateToday) - Year(Bdate) - 1
Else
Age = Year(DateToday) - Year(Bdate)
End If
End Function
 
All other issues aside, if I had 21.36 and wanted 21 I'd just use the int() function.
 
Round([FieldName],0)

Ken, isn't Int() like Fix() and only gives the whole number to the left of the decimal.
 
Based on:

"21.36, I want it to be 21. Similiarly, if their age is 21.95, I still want it to be 21"

It looks like he's always rounding down. Which would be the same as taking the integer portion wouldn't it?
 
Forgot about.:D

Whereas this Round([FieldName],0) causes premature ageing:D but get your birthday present early
 
Since it was not mentioned I must be missing something on his age calculation.

/365 won't be accurate.

Since he has a date 7/1/2008-birthday I assume the idea is to get the age of the person at that date. Would this not be better, both for accuracy and eliminating rounding

DateDiff("yyyy",[CLDOB],[EntryDate])+([EntryDate]<DateSerial(Year([EntryDate]),Month([CLDOB]),Day([CLDOB])))

With [entrydate] being the date for measuring the age of the person "at that date"
 
Try this

If Month(DateToday) < Month(Bdate) Or (Month(DateToday) = Month(Bdate) And Day(DateToday) < Day(Bdate)) Then
Age = Year(DateToday) - Year(Bdate) - 1
Else
Age = Year(DateToday) - Year(Bdate)
End If
End Function


This is a much better solution than dividing the date difference by 365. Not every year has 365 days.
 
in your code, you could try

((#7/1/2008#-[Date of Birth])\365

the \ instead of / does integer division and therefore rounds down.
 
Hi -

That's a potentially inaccurate method of computing age.

Try this:

dteEnd = date()-1
dob = #1/16/53#

Code:
? DateDiff("yyyy", DOB, dteEnd) + (DateSerial(year(dteEnd), month(DOB), day(DOB)) > dteEnd)
 55

The (DateSerial(year(dteEnd), month(DOB), day(DOB)) > dteEnd) is a boolean statement that equates to -1 if True, 0 if False.

Bob

Added:

Using your method:

? (dteEnd-dob)/365
56.0328767123288

...which, even if rounded down, would be 56 -- off by a year.
 
Last edited:
:eek:

I have the following formula in a query, and am trying to get it to stop rounding up. I am trying to determine someone's age as of 7/1/08 with this formula Age Band: ((#7/1/2008#-[Date of Birth])/365), but I can't seem to get any formula to work.

Example: If someone's age calculates to 21.36, I want it to be 21. Similiarly, if their age is 21.95, I still want it to be 21.

I'm going to need to purchase a good single malt scotch if I don't get this resolved!

Thanks in advance,

DR


I like to use this function.

Place the code in a module:

Code:
Public Function AgeYMD(DOB As Date, today As Date, Optional WithMonths As Boolean = False, _
    Optional WithDays As Boolean = False, Optional DisplayWithWords As Boolean = False) As Variant
    'Author:    © Copyright 2001 Pacific Database Pty Limited
    '           Graham R Seach gseach@pacificdb.com.au
    '           Phone: +61 2 9872 9594  Fax: +61 2 9872 9593
    '
    '           You may freely use and distribute this code
    '           with any applications you may develop, on the
    '           condition that the copyright notice remains
    '           unchanged, and intact as part of the code. You
    '           may not sell or publish this code in any form
    '           without the express written permission of the
    '           copyright holder.
    '
    'Description:   This function calculates a person's age,
    '               given their date of birth, and a second date.
    '
    'Inputs:    DOB:        The person's date of birth
    '           Today:      The second date (ostensibly today)
    '           WithMonths: Boolean - If True, displays months
    '           DisplayWithWords:   Boolean - If True, displays
    '                               (ie: years / months)
    '
    'Outputs:   On error: Null
    '           On no error: Variant containing person's age in
    '               years, months and days (if selected).
    '               If DisplayWithWords = False:
    '                   Months and days, if selected, are shown
    '                   to the right of the decimal point, but
    '                   are the actual number of months and days,
    '                   not a fraction of the year. For example,
    '                   44.11.03 = 44 years 11 months and 3 days.
    '               If DisplayWithWords = True:
    '                   Output example: "44 years 11 months 3 days",
    '                   except where months = 0, in which case, no
    '                   months are shown.
    
    On Error GoTo AgeYMD_ErrorHandler
    
    Dim iYears As Integer
    Dim iMonths As Integer
    Dim iDays As Integer
    Dim dTempDate As Date
    
    'Check that the dates are valid
    If Not (IsDate(DOB)) Or Not (IsDate(today)) Then
        DoCmd.Beep
        MsgBox "Invalid date.", vbOKOnly + vbInformation, "Invalid date"
        GoTo AgeYMD_ErrorHandler
    End If
    
    'Check that DOB < Today
    If DOB > today Then
        DoCmd.Beep
        MsgBox "Today must be greater than DOB.", _
            vbOKOnly + vbInformation, "Invalid date position"
        GoTo AgeYMD_ErrorHandler
    End If
    
    iYears = DateDiff("yyyy", DOB, today) - _
        IIf(DateAdd("yyyy", DateDiff("yyyy", DOB, today), DOB) > today, 1, 0)
    dTempDate = DateAdd("yyyy", iYears, DOB)
    
    If WithMonths Then
        iMonths = DateDiff("m", dTempDate, today) - _
            IIf(DateAdd("m", iMonths, DateAdd("yyyy", iYears, DOB)) > today, 1, 0)
        dTempDate = DateAdd("m", iMonths, dTempDate)
    End If
    
    If WithDays Then
        iDays = today - dTempDate
    End If
    
    'Format the output
    If DisplayWithWords Then
        'Display the output in words
        AgeYMD = IIf(iYears > 0, iYears & " year" & IIf(iYears <> 1, "s ", " "), "")
        AgeYMD = AgeYMD & IIf(WithMonths, iMonths & " month" & IIf(iMonths <> 1, "s ", " "), "")
        AgeYMD = Trim(AgeYMD & IIf(WithDays, iDays & " day" & IIf(iDays <> 1, "s", ""), ""))
    Else
        'Display the output in the format yy.mm.dd
        AgeYMD = Trim(iYears & IIf(WithMonths, "." & Format(iMonths, "00"), "") _
            & IIf(WithDays, "." & Format(iDays, "00"), ""))
    End If
    
Exit_AgeYMD:
    Exit Function
    
AgeYMD_ErrorHandler:
    AgeYMD = Null
    Resume Exit_AgeYMD
End Function
 
Here's another variation:

Code:
Function Agecount6(ByVal pdob As Date, _
                     Optional ByVal pEdte As Variant, _
                     Optional ByVal pWhat As Variant) As String

'*************************************************  ****
'Purpose:   Display age or difference between
'           two dates with options to display
'           in any variation of years, months,
'           days.
'Coded by:  raskew
'Inputs:    1) ? Agecount6(#3-Mar-80#) 'defaults
'                to current date & "ymd" display
'
'           2) ? Agecount6(#3-Mar-80#, "4/25/04")
'                Uses PEdte in place of date(),
'                and default "ymd" display

'           3) ? Agecount6(#3-Mar-80#, "4/25/04", "d")
'                 Same as 2), but with display as days
'
'Output:    1)  24 years, 1 month, 15 days
'           2)  24 years, 1 month, 22 days
'           3)  8819 days
'*************************************************  ****
                   
Dim dte2      As Date
Dim dteMyDate As Date
Dim intHold   As Integer
Dim n         As Integer
Dim strHold   As String
Dim strHold2  As String
Dim strTemp   As String
Dim strWhat   As String

    strWhat = IIf(IsMissing(pWhat), "ymd", pWhat)
    
    dteMyDate = pdob
    dte2 = IIf(IsMissing(pEdte), Date, pEdte)
    For n = 1 To Len(strWhat)
       strHold = Mid(strWhat, n, 1)
       Select Case strHold

          Case "y"
             intHold = DateDiff("yyyy", dteMyDate, dte2) + _
                      (dte2 < DateSerial(year(dte2), month(dteMyDate), day(dteMyDate)))
             dteMyDate = DateAdd("yyyy", intHold, dteMyDate)
             strHold2 = strHold2 & LTrim(str(intHold)) & " year" & IIf(intHold <> 1, "s, ", ", ")

          Case "m"
             intHold = DateDiff("m", dteMyDate, dte2) + (day(dteMyDate) > day(dte2))
             dteMyDate = DateAdd("m", intHold, dteMyDate)
             strHold2 = strHold2 & LTrim(str(intHold)) & " " & "month" & IIf(intHold <> 1, "s, ", ", ")

          Case "d"
             intHold = DateDiff("d", dteMyDate, dte2)
             strHold2 = strHold2 & LTrim(str(intHold)) & " " & "day" & IIf(intHold <> 1, "s", "")

       End Select
    Next n
    
    Agecount6 = strHold2

End Function

Bob
 
Raskew,

You win the prize with that one:) and with Left() you get two for the price of one.

55 years, 11 months, 21 days

56 years, 0 months, 0 days

I could not get HiTechCoach's working but obviously I was doing it wrong.
 
in your code, you could try

((#7/1/2008#-[Date of Birth])\365

the \ instead of / does integer division and therefore rounds down.

Gemme-the-husky: Thanks for this awesome little slash trick. I had no idea this would work, but it does exactly what I needed.

Thanks to all for your suggestions. I've got them in my toolbox as well now.

DR
 
Hi -

While a neat trick, the potential inaccuracy still exists.
Example (today is #01/16/09#)

Code:
dteEnd = date()
dob = #1/17/53#
? (dteEnd-dob)\365 
 56 

versus
  
? (dteEnd - dob)/365
 56.0356164383562

Problem being, he won't turn 56 until tomorrow (#01/17/09#)

Bob
 
in your code, you could try

((#7/1/2008#-[Date of Birth])\365

the \ instead of / does integer division and therefore rounds down.

Try this...

((Date()-[date of birth])\365 so you don't have to rewrite the current date on the next run...
 
There is not an average of 365 days per year. Leap years (366 days) get in the way.

If you take a normal* 4-year period, you'll have ((3 * 365) + 366)/4 = 365.25. But this can get even murkier. Take a 9-year period of 2000 - 2009. You'll have 3 leap years (2000, 2004, 2008) and 6 normal years. But, take a 9-year period of 2001 - 2010. You'll have 2 leap years (2004, 2008) and 7 normal years.

This is why your rounding method is potentially inaccurate!

Go back up to Post #10 and try applying that logic. It should correctly return Age, regardless of start and end dates.

* The leap-year situation gets even more fun around the turn of the century. In order for a millenium year to be a leap year, it must be evenly divisible by both 4 (what we normally use to determine a leap year) and 400. Thus, 2000 was a leap year, 1900, 1800 and 1700 were not.

Bob
 
Last edited:

Users who are viewing this thread

Back
Top Bottom