Home > Software engineering >  How to calculate age based on current date
How to calculate age based on current date

Time:12-16

I am trying to calculate the age of an individual.

I would like the age to be calculated to the exact as possible. However, if the age is on the same date, it should calculate the age assume it's already his birthday.

EXAMPLE: Today date: Dec 15, 2020
user #1: DOB: Dec 14, 2005 (AGE: 15)
user #2: DOB: Dec 16, 2005 (AGE: 14)
user #3: DOB: Dec 15, 2005 (AGE: 15)

I have this query, but for user #3, it is giving me age 14 when it should be 15.

SELECT
USER,
DATE_OF_BIRTH, 
FLOOR(DATEDIFF(DAY, B.DATE_OF_BIRTH, GETDATE())/365.25) AS CALCULATED_AGE
FROM TBL_A

CodePudding user response:

I think you could do it using the MONTHS_BETWEEN function.

select floor(months_between(getdate(), date_of_birth) / 12) from tbl_a

CodePudding user response:

I have to assume this question is not being done in Snowflake, as the results are off by one.

with mytable(user, dob, age_expected) as (
    select * from values
         (1, '2005-12-14'::date, 15),
         (2, '2005-12-16'::date, 14),
         (3, '2005-12-15'::date, 15)
)
SELECT
    user
    ,dob 
    ,'2022-12-15'::date as todays_date
    ,DATEDIFF(DAY, dob, todays_date) as gap_days
    ,gap_days/365.25 as d365
    ,floor(d365) as f0
    ,FLOOR(DATEDIFF(DAY, dob, todays_date)/365.25) AS CALCULATED_AGE
FROM mytable
USER DOB TODAYS_DATE GAP_DAYS D365 F0 CALCULATED_AGE
1 2005-12-14 2022-12-15 6,210 17.002053 17 17
2 2005-12-16 2022-12-15 6,208 16.996578 16 16
3 2005-12-15 2022-12-15 6,209 16.999316 16 16

So if we deconstruct what is happening, move the month of interest back to november so the before after months case can be seen, and move the "current date" back 2 years so we get the stated expected results 14/15:

with mytable(user, dob, age_expected) as (
    select * from values
         (1, '2005-10-15'::date, 15),    

         (2, '2005-11-14'::date, 15),
         (3, '2005-11-16'::date, 14),
         (4, '2005-11-15'::date, 15),

         (5, '2005-12-15'::date, 14)
)
SELECT
    user
    ,dob 
    ,age_expected
    ,'2020-11-15'::date as todays_date
    ,year(dob) as dob_y
    ,month(dob) as dob_m
    ,day(dob) as dob_d
    ,year(todays_date) as today_y
    ,month(todays_date) as today_m
    ,day(todays_date) as today_d
    ,DATEDIFF(DAY, dob, todays_date)/365.25 as float_val
    ,today_y - dob_y as y_dif
        ,case 
        when today_m < dob_m then 'a'
        when today_m > dob_m then 'b'
        when today_d < dob_d then 'c'
        when today_d >= dob_d then 'd'
    end as pick
    ,case 
        when today_m < dob_m then y_dif -1 
        when today_m > dob_m then y_dif
        when today_d < dob_d then y_dif -1 
        when today_d >= dob_d then y_dif
    end as result

FROM mytable
order by dob
USER DOB AGE_EXPECTED TODAYS_DATE DOB_Y DOB_M DOB_D TODAY_Y TODAY_M TODAY_D FLOAT_VAL Y_DIF PICK RESULT
1 2005-10-15 15 2020-11-15 2,005 10 15 2,020 11 15 15.085558 15 b 15
2 2005-11-14 15 2020-11-15 2,005 11 14 2,020 11 15 15.003422 15 d 15
4 2005-11-15 15 2020-11-15 2,005 11 15 2,020 11 15 15.000684 15 d 15
3 2005-11-16 14 2020-11-15 2,005 11 16 2,020 11 15 14.997947 15 c 14
5 2005-12-15 14 2020-11-15 2,005 12 15 2,020 11 15 14.918549 15 a 14

So using the numbers you state, would would, but it we move the current date back to 2022 those numbers don't work, due to the stride of actual number of daylight days. so you just stick to the partial math method which can be simplefied to:

with mytable(user, dob, age_expected) as (
    select * from values
         (1, '2005-11-15'::date, 15),    

         (2, '2005-12-14'::date, 15),
         (3, '2005-12-16'::date, 14),
         (4, '2005-12-15'::date, 15),

         (5, '2006-01-15'::date, 14)
)
SELECT
    user
    ,dob 
    ,age_expected
    ,CURRENT_DATE
    ,case 
        when month(CURRENT_DATE) < month(dob) then year(CURRENT_DATE) - year(dob) -1 
        when month(CURRENT_DATE) > month(dob) then year(CURRENT_DATE) - year(dob)
        when day(CURRENT_DATE) < day(dob) then year(CURRENT_DATE) - year(dob) -1 
        when day(CURRENT_DATE) >= day(dob) then year(CURRENT_DATE) - year(dob)
    end as result

FROM mytable
order by dob

gives:

USER DOB AGE_EXPECTED CURRENT_DATE RESULT
1 2005-11-15 15 2022-12-15 17
2 2005-12-14 15 2022-12-15 17
4 2005-12-15 15 2022-12-15 17
3 2005-12-16 14 2022-12-15 16
5 2006-01-15 14 2022-12-15 16
  • Related