답변:
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))
date.today()
출생지와 다를 수있는 현지 시간대의 날짜를 반환합니다. 시간대를 명시 적으로 사용해야
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
업데이트 : 사용 대니의 솔루션은 , 그것은 더 나은
except
블록은 발생할 수있는 하나의 특정 예외 만 포착해야합니다.
ValueError
. 업데이트되었습니다.
def calculate_age(dob)
datetime.date(2014, 1, 1)
-1을 주면 0을 주어야합니다 today > dob
. DOB가 지난해가 아닌 과거에 있는지 확인 중입니다. datetime.date.today()
연도 정보가 포함되어 있으므로 솔루션에서 현재 연도로 대체합니다.
from datetime import date
days_in_year = 365.2425
age = int((date.today() - birth_date).days / days_in_year)
파이썬 3에서는 다음과 같이 나눌 수 있습니다 datetime.timedelta
.
from datetime import date, timedelta
age = (date.today() - birth_date) // timedelta(days=365.2425)
365.25
)과 그레고리력 연도 ( 365.2425
)의 차이는 130 세 미만인 경우 하루보다 짧습니다.
(date(2017, 3, 1) - date(2004, 3, 1)) / timedelta(days=365.2425)
should return 13
하지만을 반환합니다 12
. 바닥이없는 경우 결과는 12.999582469181433
입니다.
@ [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)`
가장 간단한 방법은 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
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
불행히도, 사용하는 가장 큰 단위는 일이며 윤년으로 인해 계산이 유효하지 않기 때문에 타임 델라 타를 사용할 수 없습니다. 따라서 지난 해가 가득 차 있지 않은 경우 몇 년을 찾은 다음 1 씩 조정하십시오.
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 년 2 월 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()
성능 저하 에 대해 여러 번의 전화를 거는 것은 우스운 일이지만, 매우 특별한 경우는 아닙니다. 변수를 사용해야하는 실제 이유는 데이터 불일치의 위험 때문입니다.
이 시나리오의 고전은 2 월 29 일에 태어난 사람들과 관계가 있습니다. 예 : 투표, 자동차 운전, 음주 등을하려면 18 세 이상이어야합니다. 2004-02-29 년에 태어난 경우 첫 번째 날은 다음과 같습니다. 2022-02 -28 또는 2022-03-01? AFAICT, 주로 첫 번째이지만, 몇 가지 살인이 후자를 말할 수 있습니다.
다음은 그 날에 태어난 인구의 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
다음은 사람의 나이를 몇 년 또는 몇 달 또는 몇 일로 찾는 솔루션입니다.
사람의 생년월일이 2012-01-17T00 : 00 : 00이라고 가정 하면 2013-01-16T00 : 00 : 00의 나이 는 11 개월입니다.
그가 태어난 경우 또는 00 : 2012-12-17T00 00 , 그의 나이 2013-01-12T00 : 00 : 00이 될 것입니다 이십육일
또는 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")
이제 2000-02-29T00 : 00 : 00 과 같은 문자열로 get_date_format () 을 공급해야합니다 .
get_person_age (date_birth, date_today)에 공급할 날짜 유형 객체로 변환합니다 .
get_person_age (date_birth, date_today) 함수 는 연령을 문자열 형식으로 반환합니다.
Danny의 솔루션을 확장 하지만 젊은 사람들의 연령을보고하는 모든 종류의 방법으로 (오늘은 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
올바른 구현을 보지 못했지만이 방법으로 코드를 코딩했습니다 ...
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)
29 일에 태어 났을 때 2 월 28 일에 "18"이라는 가정은 잘못되었습니다. 경계를 바꾸는 것은 생략 될 수 있습니다 ... 내 코드의 개인적인 편의 일뿐입니다 :)
Danny W. Adair Answer으로 확장하여 월도 받으십시오.
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
날짜 / 시간 가져 오기
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
더 쉽게 읽고 이해하기 위해 약간 수정 된 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
datetime
모듈로 충분하지 않은 경우 시도해 볼 수 있습니다. labix.org/python-dateutil