web-dev-qa-db-fra.com

Âge à partir de la date de naissance en python

Comment trouver un âge en python à partir de la date d'aujourd'hui et une date de naissance? La date de naissance est un dateField dans un modèle Django.

133
tkalve

Cela peut être fait beaucoup plus simplement si on considère que int (True) vaut 1 et int (False) vaut 0:

from datetime import date

def calculate_age(born):
    today = date.today()
    return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
228
Danny W. Adair
from datetime import date

def calculate_age(born):
    today = date.today()
    try: 
        birthday = born.replace(year=today.year)
    except ValueError: # raised when birth date is February 29 and the current year is not a leap year
        birthday = born.replace(year=today.year, month=born.month+1, day=1)
    if birthday > today:
        return today.year - born.year - 1
    else:
        return today.year - born.year

Mise à jour: Utilisez La solution de Danny , c'est mieux

66
mpen
from datetime import date

days_in_year = 365.2425    
age = int((date.today() - birth_date).days / days_in_year)

En Python 3, vous pouvez effectuer une division sur datetime.timedelta:

from datetime import date, timedelta

age = (date.today() - birth_date) // timedelta(days=365.2425)
14
TheOne

Comme suggéré par @ [Tomasz Zielinski] et @Williams python-dateutil ne peut le faire que 5 lignes.

from dateutil.relativedelta import *
from datetime import date
today = date.today()
dob = date(1982, 7, 5)
age = relativedelta(today, dob)

>>relativedelta(years=+33, months=+11, days=+16)`
8
Arun Kumar Khattri

Le moyen le plus simple est d'utiliser python-dateutil

import datetime

import dateutil

def birthday(date):
    # Get the current date
    now = datetime.datetime.utcnow()
    now = now.date()

    # Get the difference between the current date and the birthday
    age = dateutil.relativedelta.relativedelta(now, date)
    age = age.years

    return age
8
user1569050
from datetime import date

def age(birth_date):
    today = date.today()
    y = today.year - birth_date.year
    if today.month < birth_date.month or today.month == birth_date.month and today.day < birth_date.day:
        y -= 1
    return y
6
gzerone

Malheureusement, vous ne pouvez pas simplement utiliser timedelata car la plus grande unité utilisée est le jour et les années bissextiles vous invalideront. Par conséquent, trouvons le nombre d’années, puis ajustons-en une si la dernière année n’est pas complète:

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:

Cette solution provoque vraiment une exception lorsque le 29 février entre en jeu. Voici chèque correct:

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:

Il est ridicule d’appeler plusieurs appels pour que now() devienne performant. Cela n’a pas d’importance, sauf dans des cas extrêmement particuliers. La véritable raison d'utiliser une variable est le risque d'incohérence des données.

5
Alexander Lebedev

Le scénario classique dans ce scénario est de savoir quoi faire avec les personnes nées le 29 février. Exemple: vous devez avoir 18 ans pour voter, conduire une voiture, acheter de l'alcool, etc. Si vous êtes né le 2004-02-29, quel est le premier jour où vous êtes autorisé à faire de telles choses: 2022-02 -28 ou 2022-03-01? AFAICT, principalement le premier, mais quelques killjoys pourraient dire le dernier.

Voici le code qui s'adresse aux environ 0,068% de la population née ce jour-là:

def age_in_years(from_date, to_date, leap_day_anniversary_Feb28=True):
    age = to_date.year - from_date.year
    try:
        anniversary = from_date.replace(year=to_date.year)
    except ValueError:
        assert from_date.day == 29 and from_date.month == 2
        if leap_day_anniversary_Feb28:
            anniversary = datetime.date(to_date.year, 2, 28)
        else:
            anniversary = datetime.date(to_date.year, 3, 1)
    if to_date < anniversary:
        age -= 1
    return age

if __== "__main__":
    import datetime

    tests = """

    2004  2 28 2010  2 27  5 1
    2004  2 28 2010  2 28  6 1
    2004  2 28 2010  3  1  6 1

    2004  2 29 2010  2 27  5 1
    2004  2 29 2010  2 28  6 1
    2004  2 29 2010  3  1  6 1

    2004  2 29 2012  2 27  7 1
    2004  2 29 2012  2 28  7 1
    2004  2 29 2012  2 29  8 1
    2004  2 29 2012  3  1  8 1

    2004  2 28 2010  2 27  5 0
    2004  2 28 2010  2 28  6 0
    2004  2 28 2010  3  1  6 0

    2004  2 29 2010  2 27  5 0
    2004  2 29 2010  2 28  5 0
    2004  2 29 2010  3  1  6 0

    2004  2 29 2012  2 27  7 0
    2004  2 29 2012  2 28  7 0
    2004  2 29 2012  2 29  8 0
    2004  2 29 2012  3  1  8 0

    """

    for line in tests.splitlines():
        nums = [int(x) for x in line.split()]
        if not nums:
            print
            continue
        datea = datetime.date(*nums[0:3])
        dateb = datetime.date(*nums[3:6])
        expected, anniv = nums[6:8]
        age = age_in_years(datea, dateb, anniv)
        print datea, dateb, anniv, age, expected, age == expected

Voici le résultat:

2004-02-28 2010-02-27 1 5 5 True
2004-02-28 2010-02-28 1 6 6 True
2004-02-28 2010-03-01 1 6 6 True

2004-02-29 2010-02-27 1 5 5 True
2004-02-29 2010-02-28 1 6 6 True
2004-02-29 2010-03-01 1 6 6 True

2004-02-29 2012-02-27 1 7 7 True
2004-02-29 2012-02-28 1 7 7 True
2004-02-29 2012-02-29 1 8 8 True
2004-02-29 2012-03-01 1 8 8 True

2004-02-28 2010-02-27 0 5 5 True
2004-02-28 2010-02-28 0 6 6 True
2004-02-28 2010-03-01 0 6 6 True

2004-02-29 2010-02-27 0 5 5 True
2004-02-29 2010-02-28 0 5 5 True
2004-02-29 2010-03-01 0 6 6 True

2004-02-29 2012-02-27 0 7 7 True
2004-02-29 2012-02-28 0 7 7 True
2004-02-29 2012-02-29 0 8 8 True
2004-02-29 2012-03-01 0 8 8 True
4
John Machin

Si vous souhaitez imprimer ceci dans une page utilisant des modèles Django, alors ce qui suit pourrait suffire:

{{ birth_date|timesince }}
2
Anoyz

Développer la solution de Danny , mais avec toutes sortes de façons de signaler les âges des jeunes gens (notez qu'aujourd'hui, datetime.date(2015,7,17)):

def calculate_age(born):
    '''
        Converts a date of birth (dob) datetime object to years, always rounding down.
        When the age is 80 years or more, just report that the age is 80 years or more.
        When the age is less than 12 years, rounds down to the nearest half year.
        When the age is less than 2 years, reports age in months, rounded down.
        When the age is less than 6 months, reports the age in weeks, rounded down.
        When the age is less than 2 weeks, reports the age in days.
    '''
    today = datetime.date.today()
    age_in_years = today.year - born.year - ((today.month, today.day) < (born.month, born.day))
    months = (today.month - born.month - (today.day < born.day)) %12
    age = today - born
    age_in_days = age.days
    if age_in_years >= 80:
        return 80, 'years or older'
    if age_in_years >= 12:
        return age_in_years, 'years'
    Elif age_in_years >= 2:
        half = 'and a half ' if months > 6 else ''
        return age_in_years, '%syears'%half
    Elif months >= 6:
        return months, 'months'
    Elif age_in_days >= 14:
        return age_in_days/7, 'weeks'
    else:
        return age_in_days, 'days'

Exemple de code:

print '%d %s' %calculate_age(datetime.date(1933,6,12)) # >=80 years
print '%d %s' %calculate_age(datetime.date(1963,6,12)) # >=12 years
print '%d %s' %calculate_age(datetime.date(2010,6,19)) # >=2 years
print '%d %s' %calculate_age(datetime.date(2010,11,19)) # >=2 years with half
print '%d %s' %calculate_age(datetime.date(2014,11,19)) # >=6 months
print '%d %s' %calculate_age(datetime.date(2015,6,4)) # >=2 weeks
print '%d %s' %calculate_age(datetime.date(2015,7,11)) # days old

80 years or older
52 years
5 years
4 and a half years
7 months
6 weeks
7 days
2
Dannid

Voici une solution pour trouver l’âge d’une personne en années, en mois ou en jours.

Disons que la date de naissance d'une personne est 2012-01-17T00: 00: 00 Par conséquent, son âge est/ 2013-01-16T00: 00: 00 sera 11 mois

ou s'il est né le 2012-12-17T00: 00: 00 , son âge le 2013-01-12T00: 00: 00 sera 26 jours

ou s'il est né le 2000-02-29T00: 00: 00 , son âge le 2012-02-29T00: 00: 00 sera 12 ans

Vous aurez besoin de importer datetime .

Voici le code:

def get_person_age(date_birth, date_today):

"""
At top level there are three possibilities : Age can be in days or months or years.
For age to be in years there are two cases: Year difference is one or Year difference is more than 1
For age to be in months there are two cases: Year difference is 0 or 1
For age to be in days there are 4 possibilities: Year difference is 1(20-dec-2012 - 2-jan-2013),
                                                 Year difference is 0, Months difference is 0 or 1
"""
years_diff = date_today.year - date_birth.year
months_diff = date_today.month - date_birth.month
days_diff = date_today.day - date_birth.day
age_in_days = (date_today - date_birth).days

age = years_diff
age_string = str(age) + " years"

# age can be in months or days.
if years_diff == 0:
    if months_diff == 0:
        age = age_in_days
        age_string = str(age) + " days"
    Elif months_diff == 1:
        if days_diff < 0:
            age = age_in_days
            age_string = str(age) + " days"
        else:
            age = months_diff
            age_string = str(age) + " months"
    else:
        if days_diff < 0:
            age = months_diff - 1
        else:
            age = months_diff
        age_string = str(age) + " months"
# age can be in years, months or days.
Elif years_diff == 1:
    if months_diff < 0:
        age = months_diff + 12
        age_string = str(age) + " months" 
        if age == 1:
            if days_diff < 0:
                age = age_in_days
                age_string = str(age) + " days" 
        Elif days_diff < 0:
            age = age-1
            age_string = str(age) + " months"
    Elif months_diff == 0:
        if days_diff < 0:
            age = 11
            age_string = str(age) + " months"
        else:
            age = 1
            age_string = str(age) + " years"
    else:
        age = 1
        age_string = str(age) + " years"
# The age is guaranteed to be in years.
else:
    if months_diff < 0:
        age = years_diff - 1
    Elif months_diff == 0:
        if days_diff < 0:
            age = years_diff - 1
        else:
            age = years_diff
    else:
        age = years_diff
    age_string = str(age) + " years"

if age == 1:
    age_string = age_string.replace("years", "year").replace("months", "month").replace("days", "day")

return age_string

Certaines fonctions supplémentaires utilisées dans les codes ci-dessus sont:

def get_todays_date():
    """
    This function returns todays date in proper date object format
    """
    return datetime.now()

Et

def get_date_format(str_date):
"""
This function converts string into date type object
"""
str_date = str_date.split("T")[0]
return datetime.strptime(str_date, "%Y-%m-%d")

Maintenant, nous devons alimenter get_date_format () avec les chaînes telles que 2000-02-29T00: 00: 00

Il le convertira en objet de type date qui doit être alimenté dans get_person_age (date_birth, date_today) .

La fonction get_person_age (date_birth, date_today) renverra l'âge au format chaîne.

2
Shubham L

Étendre à Danny W. Adair Réponse , pour obtenir le mois aussi

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
1
SmartManoj

Comme je n'ai pas vu la bonne mise en œuvre, j'ai recodé le mien de cette façon ...

    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)

Supposer être "le 18" le 28 février quand on est né le 29 est tout simplement faux. Échanger les limites peut être omis ... c'est juste un avantage personnel pour mon code :)

1
Thomas

Légèrement modifié Solution de Danny pour faciliter la lecture et la compréhension

    from datetime import date

    def calculate_age(birth_date):
        today = date.today()
        age = today.year - birth_date.year
        full_year_passed = (today.month, today.day) < (birth_date.month, birth_date.day)
        if not full_year_passed:
            age -= 1
        return age
0
pecos pest

importer date/heure

def age(date_of_birth):
    if date_of_birth > datetime.date.today().replace(year = date_of_birth.year):
        return datetime.date.today().year - date_of_birth.year - 1
    else:
        return datetime.date.today().year - date_of_birth.year

Dans ton cas:

import datetime

# your model
def age(self):
    if self.birthdate > datetime.date.today().replace(year = self.birthdate.year):
        return datetime.date.today().year - self.birthdate.year - 1
    else:
        return datetime.date.today().year - self.birthdate.year
0
doomatel
import datetime

La date d'aujourd'hui

td=datetime.datetime.now().date() 

Ta date de naissance

bd=datetime.date(1989,3,15)

Ton âge

age_years=int((td-bd).days /365.25)
0
Aseem