Age from birthdate in python

2019-01-04 16:37发布

How can I find an age in python from today's date and a persons birthdate? The birthdate is a from a DateField in a Django model.

15条回答
Deceive 欺骗
2楼-- · 2019-01-04 17:30

As I did not see the correct implementation, I recoded mine this way...

    def age_in_years(from_date, to_date=datetime.date.today()):
  if (DEBUG):
    logger.debug("def age_in_years(from_date='%s', to_date='%s')" % (from_date, to_date))

  if (from_date>to_date): # swap when the lower bound is not the lower bound
    logger.debug('Swapping dates ...')
    tmp = from_date
    from_date = to_date
    to_date = tmp

  age_delta = to_date.year - from_date.year
  month_delta = to_date.month - from_date.month
  day_delta = to_date.day - from_date.day

  if (DEBUG):
    logger.debug("Delta's are : %i  / %i / %i " % (age_delta, month_delta, day_delta))

  if (month_delta>0  or (month_delta==0 and day_delta>=0)): 
    return age_delta 

  return (age_delta-1)

Assumption of being "18" on the 28th of Feb when born on the 29th is just wrong. Swapping the bounds can be left out ... it is just a personal convenience for my code :)

查看更多
成全新的幸福
3楼-- · 2019-01-04 17:37

Extend to Danny W. Adair Answer, to get month also

def calculate_age(b):
    t = date.today()
    c = ((t.month, t.day) < (b.month, b.day))
    c2 = (t.day< b.day)
    return t.year - b.year - c,c*12+t.month-b.month-c2
查看更多
来,给爷笑一个
4楼-- · 2019-01-04 17:38

Unfortunately, you cannot just use timedelata as the largest unit it uses is day and leap years will render you calculations invalid. Therefore, let's find number of years then adjust by one if the last year isn't full:

from datetime import date
birth_date = date(1980, 5, 26)
years = date.today().year - birth_date.year
if (datetime.now() - birth_date.replace(year=datetime.now().year)).days >= 0:
    age = years
else:
    age = years - 1

Upd:

This solution really causes an exception when Feb, 29 comes into play. Here's correct check:

from datetime import date
birth_date = date(1980, 5, 26)
today = date.today()
years = today.year - birth_date.year
if all((x >= y) for x,y in zip(today.timetuple(), birth_date.timetuple()):
   age = years
else:
   age = years - 1

Upd2:

Calling multiple calls to now() a performance hit is ridiculous, it does not matter in all but extremely special cases. The real reason to use a variable is the risk of data incosistency.

查看更多
登录 后发表回答