it-swarm.com.de

Alter ab Geburtsdatum in Python

Wie kann ich ein Alter in Python ab dem heutigen Datum und dem Geburtsdatum einer Person finden? Das Geburtsdatum stammt aus einem DateField in einem Django-Modell.

133
tkalve

Dies kann viel einfacher durchgeführt werden, da int (True) 1 ist und int (False) 0 ist.

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

Update: Benutze Dannys Lösung , es ist besser

66
mpen
from datetime import date

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

In Python 3 können Sie eine Aufteilung in datetime.timedelta vornehmen:

from datetime import date, timedelta

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

Wie von @ [Tomasz Zielinski] und @Williams python-dateutil vorgeschlagen, kann/machen es nur 5 Zeilen.

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

Der einfachste Weg ist die Verwendung von 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

Leider können Sie nicht einfach timedelata verwenden, da die größte Einheit, die es verwendet, der Tag ist. Finden wir also die Anzahl der Jahre und passen Sie sie um eins an, wenn das letzte Jahr nicht voll ist:

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:

Diese Lösung verursacht wirklich eine Ausnahme, wenn der 29. Februar ins Spiel kommt. Hier ist die richtige Prüfung:

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:

Mehrere Anrufe bei now() an einen Leistungstreffer zu appellieren, ist lächerlich, es spielt keine Rolle in allen speziellen Fällen. Der wahre Grund für die Verwendung einer Variablen ist das Risiko von Dateninkonsistenzen.

5

Das klassische Problem in diesem Szenario ist, was mit den am 29. Februar Geborenen zu tun hat. Beispiel: Sie müssen 18 Jahre alt sein, um abstimmen zu können, ein Auto zu fahren, Alkohol zu kaufen usw. Wenn Sie am 29.02.2004 geboren sind, was ist der erste Tag, an dem Sie solche Dinge tun dürfen: 2022-02 -28 oder 2022-03-01? AFAICT, meistens der erste, aber ein paar Killjoys mögen letzteren sagen.

Hier ist der Code, der die 0,068% (ungefähr) der an diesem Tag geborenen Bevölkerung berücksichtigt:

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

Hier ist die Ausgabe:

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

Wenn Sie dies auf einer Seite mit Django-Vorlagen ausdrucken möchten, reicht Folgendes aus:

{{ birth_date|timesince }}
2
Anoyz

Erweiterung auf Danny's Solution , aber mit allen Möglichkeiten, das Alter für jüngere Leute anzugeben (Anmerkung, heute ist 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'

Beispielcode:

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

Hier ist eine Lösung, um das Alter einer Person nach Jahren, Monaten oder Tagen zu bestimmen.

Nehmen wir an, das Geburtsdatum einer Person ist 2012-01-17T00: 00: Daher ist sein Alter am 2013-01-16T00: 00: 11 Monate

oder wenn er am 2012-12-17T00: 00: geboren ist, beträgt sein Alter am 2013-01-12T00: 00: 26 Tage)

oder wenn er am 2000-02-29T00: 00: geboren ist, beträgt sein Alter am 2012-02-29T00: 00: 12 Jahre

Sie müssen Datum/Uhrzeit importieren.

Hier ist der 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

Einige zusätzliche Funktionen, die in den obigen Codes verwendet werden, sind:

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

Und

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")

Jetzt müssen wir get_date_format () mit den Zeichenfolgen wie 2000-02-29T00: 00: füttern

Es konvertiert es in das Objekt vom Typ Datum, das an get_person_age (date_birth, date_today) weitergeleitet werden soll.

Die Funktion get_person_age (date_birth, date_today) gibt das Alter im Zeichenfolgenformat zurück.

2
Shubham L

Erweitere dich auf Danny W. Adair Answer , um auch einen Monat zu bekommen

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

Da ich die korrekte Implementierung nicht sah, habe ich meine so umcodiert ...

    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)

Die Annahme, am 28. Februar "18" zu sein, wenn sie am 29. Februar geboren wurde, ist einfach falsch.

1
Thomas

Leicht modifiziert Dannys Lösung zum leichteren Lesen und Verstehen

    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

datetime importieren

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

In Ihrem Fall:

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

Heutiges Datum

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

Dein Geburtstag

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

dein Alter

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