Как я могу найти возраст в python с сегодняшнего дня и дату рождения людей? Дата рождения - от DateField в модели Django.
Возраст от даты рождения в python
Ответ 1
Это можно сделать гораздо проще, учитывая, что int (True) равен 1 и int (False) равно 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))
Ответ 2
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
Обновление: Используйте решение Danny, лучше
Ответ 3
from datetime import date
days_in_year = 365.2425
age = int((date.today() - birth_date).days / days_in_year)
В Python 3 вы можете выполнить деление на datetime.timedelta
:
from datetime import date, timedelta
age = (date.today() - birth_date) // timedelta(days=365.2425)
Ответ 4
Самый простой способ - использовать 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
Ответ 5
По предложению @[Tomasz Zielinski] и @Williams python-dateutil может сделать это всего за 5 строк.
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)'
Ответ 6
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
Ответ 7
К сожалению, вы не можете просто использовать timedelata, поскольку наибольшая единица, которую он использует, - это день и високосные годы, что сделает ваши вычисления недействительными. Поэтому пусть найдет число лет, затем скорректируется на один, если последний год не заполнен:
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:
Это решение действительно вызывает исключение, когда вступает в игру 29 февраля. Здесь правильная проверка:
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:
Вызов нескольких вызовов на now()
поражает производительность, это не имеет значения во всех, кроме исключительно особых случаях. Настоящей причиной использования переменной является риск несогласованности данных.
Ответ 8
Классическая версия в этом сценарии - это то, что делать с людьми, родившимися 29-го февраля. Пример: вам нужно быть в возрасте 18 лет, чтобы проголосовать, водить машину, покупать алкоголь и т.д.... если вы родились в 2004-02-29, то, что в первый день вам разрешено делать такие вещи: 2022-02 -28, или 2022-03-01? AFAICT, в основном первый, но несколько killjoys могут сказать последнее.
Здесь код, который обслуживает 0,068% (приблизительно) населения, родившегося в этот день:
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 __name__ == "__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
Здесь вывод:
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
Ответ 9
Вот решение, чтобы найти возраст человека как годы или месяцы или дни.
Предположим, что дата рождения человека 2012-01-17T00: 00: 00 Поэтому его возраст на 2013-01-16T00: 00: 00 будет 11 месяцев
или если он родился на 2012-12-17T00: 00: 00, его возраст на 2013-01-12T00: 00: 00 будет 26 дней
или если он родился на 2000-02-29T00: 00: 00, его возраст на 2012-02-29T00: 00: 00 будет 12 лет
Вам нужно импортировать datetime.
Вот код:
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
Некоторые дополнительные функции, используемые в приведенных выше кодах, следующие:
def get_todays_date():
"""
This function returns todays date in proper date object format
"""
return datetime.now()
и
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")
Теперь нам нужно кормить get_date_format() со строками типа 2000-02-29T00: 00: 00
Он преобразует его в объект типа даты, который должен быть отправлен в get_person_age (date_birth, date_today).
Функция get_person_age (date_birth, date_today) возвращает возраст в формате строки.
Ответ 10
Если вы хотите распечатать это на странице с помощью шаблонов django, может потребоваться следующее:
{{ birth_date|timesince }}
Ответ 11
Развернувшись на Danny Solution, но со всеми возможными способами сообщать о возрасте для молодых людей (заметьте, сегодня 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'
Пример кода:
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
Ответ 12
Поскольку я не видел правильной реализации, я перекодировал мой таким образом...
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 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)
Успение быть "18" 28 февраля, когда родилось 29-го, просто неверно. Переключение границ можно оставить без внимания... это просто личное удобство для моего кода:)
Ответ 13
Расширить до Дэнни В. Адэйр Ответ, чтобы получить месяц также
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
Ответ 14
import datetime
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
В вашем случае:
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
Ответ 15
Немного изменено решение Danny для упрощения чтения и понимания
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
Ответ 16
import datetime
Сегодняшняя дата
td=datetime.datetime.now().date()
Ваша дата рождения
bd=datetime.date(1989,3,15)
Ваш возраст
age_years=int((td-bd).days /365)