몇 년이 지난 지 몇 년이 지 났는지 확인해야합니다. 현재 모듈 timedelta
에서 왔으며 datetime
몇 년으로 변환하는 방법을 모르겠습니다.
몇 년이 지난 지 몇 년이 지 났는지 확인해야합니다. 현재 모듈 timedelta
에서 왔으며 datetime
몇 년으로 변환하는 방법을 모르겠습니다.
답변:
timedelta
몇 년이 지 났는지 알기 위해서는 a 이상이 필요합니다 . 시작일 (또는 종료일)도 알아야합니다. (이것은 윤년입니다.)
가장 좋은 방법은 dateutil.relativedelta
object 를 사용하는 것이지만 타사 모듈입니다. 어떤 날짜로부터 몇 년 datetime
이 n
지 났는지 (기본값은 지금) 알고 싶다면 다음을 수행하십시오.
from dateutil.relativedelta import relativedelta
def yearsago(years, from_date=None):
if from_date is None:
from_date = datetime.now()
return from_date - relativedelta(years=years)
표준 라이브러리를 고수하고 싶다면 대답이 조금 더 복잡합니다. :
from datetime import datetime
def yearsago(years, from_date=None):
if from_date is None:
from_date = datetime.now()
try:
return from_date.replace(year=from_date.year - years)
except ValueError:
# Must be 2/29!
assert from_date.month == 2 and from_date.day == 29 # can be removed
return from_date.replace(month=2, day=28,
year=from_date.year-years)
2/29이고 18 년 전에 2/29가 없으면이 함수는 2/28을 반환합니다. 3/1을 반환하려면 마지막 return
문장을 다음과 같이 변경하십시오.
return from_date.replace(month=3, day=1,
year=from_date.year-years)
귀하의 질문에 따르면, 당신은 어떤 날로부터 몇 년이 지 났는지 알고 싶었습니다. 정수 년을 원한다고 가정하면 연간 365.25 일을 기준으로 추측 한 다음 yearsago
위에 정의 된 함수 중 하나를 사용하여 확인할 수 있습니다.
def num_years(begin, end=None):
if end is None:
end = datetime.now()
num_years = int((end - begin).days / 365.25)
if begin > yearsago(num_years, end):
return num_years - 1
else:
return num_years
datetime.now()
)에 의해 도입 된 차이가 평균 Julian ( 365.25
)과 Gregorian ( 365.2425
) 년 의 차이보다 큽니다 . . 올바른 접근 방식은 @Adam Rosenfield의 답변
18 세 이상인지 확인하려는 timedelta
경우 윤년으로 인해 일부 엣지 케이스에서 사용 이 제대로 작동하지 않습니다. 예를 들어 2000 년 1 월 1 일에 태어난 사람은 2018 년 1 월 1 일에 정확히 6575 일 후에 18 세가되고 (5 윤년 포함) 2001 년 1 월 1 일에 태어난 사람은 1 월 1 일에 정확히 6574 일 후에 18 세가됩니다. 2019 (4 년 윤년 포함). 따라서 누군가 정확히 6574 일이되었을 경우, 생년월일에 대한 약간의 정보를 모르면 17 세 또는 18 세인지 여부를 판단 할 수 없습니다.
이를 수행하는 올바른 방법은 2 년을 뺀 다음 현재 월 / 일이 출생 월 / 일보다 먼저 오면 날짜를 직접 계산하여 나이를 계산하는 것입니다.
먼저 가장 세부적인 수준에서 문제를 정확하게 해결할 수 없습니다. 연도는 다양하며 연도에 대한 명확한 "올바른 선택"은 없습니다.
즉, "자연"(아마 초) 단위의 차이를 얻고 그와 연도의 비율로 나눕니다. 예 :
delta_in_days / (365.25)
delta_in_seconds / (365.25*24*60*60)
...또는 무엇이든. 몇 년보다 잘 정의되어 있지 않기 때문에 몇 개월을 멀리하십시오.
다음은 업데이트 된 DOB 함수입니다. 인간과 같은 방식으로 생일을 계산합니다.
import datetime
import locale
# Source: https://en.wikipedia.org/wiki/February_29
PRE = [
'US',
'TW',
]
POST = [
'GB',
'HK',
]
def get_country():
code, _ = locale.getlocale()
try:
return code.split('_')[1]
except IndexError:
raise Exception('Country cannot be ascertained from locale.')
def get_leap_birthday(year):
country = get_country()
if country in PRE:
return datetime.date(year, 2, 28)
elif country in POST:
return datetime.date(year, 3, 1)
else:
raise Exception('It is unknown whether your country treats leap year '
+ 'birthdays as being on the 28th of February or '
+ 'the 1st of March. Please consult your country\'s '
+ 'legal code for in order to ascertain an answer.')
def age(dob):
today = datetime.date.today()
years = today.year - dob.year
try:
birthday = datetime.date(today.year, dob.month, dob.day)
except ValueError as e:
if dob.month == 2 and dob.day == 29:
birthday = get_leap_birthday(today.year)
else:
raise e
if today < birthday:
years -= 1
return years
print(age(datetime.date(1988, 2, 29)))
def age(dob):
import datetime
today = datetime.date.today()
if today.month < dob.month or \
(today.month == dob.month and today.day < dob.day):
return today.year - dob.year - 1
else:
return today.year - dob.year
>>> import datetime
>>> datetime.date.today()
datetime.date(2009, 12, 1)
>>> age(datetime.date(2008, 11, 30))
1
>>> age(datetime.date(2008, 12, 1))
1
>>> age(datetime.date(2008, 12, 2))
0
여기에 언급되지 않은 다른 타사 라이브러리는이 작업에 mxDateTime (python datetime
및 타사의 이전 버전 timeutil
)을 사용할 수 있습니다.
위에서 언급 한 내용 yearsago
은 다음과 같습니다.
from mx.DateTime import now, RelativeDateTime
def years_ago(years, from_date=None):
if from_date == None:
from_date = now()
return from_date-RelativeDateTime(years=years)
첫 번째 매개 변수는 DateTime
인스턴스 일 것으로 예상됩니다 .
일반 datetime
으로 변환하려면 DateTime
1 초 정밀도로 이것을 사용할 수 있습니다)
def DT_from_dt_s(t):
return DT.DateTimeFromTicks(time.mktime(t.timetuple()))
또는 1 마이크로 초 정밀도의 경우 :
def DT_from_dt_u(t):
return DT.DateTime(t.year, t.month, t.day, t.hour,
t.minute, t.second + t.microsecond * 1e-6)
그렇습니다.이 단일 작업에 대한 종속성을 추가하는 것은 timeutil (Rick Copeland가 제안한)을 사용하는 것보다 확실히 과잉 일 것입니다.
결국 당신이 가진 것은 수학 문제입니다. 4 년마다 하루가 더 있으면 타임 델타를 365 일이 아니라 365 * 4 + 1로 며칠 단위로 나눌 수 있습니다. 그러면 4 년이됩니다. 그런 다음 다시 4로 나눕니다. timedelta / ((365 * 4) +1) / 4 = timedelta * 4 / (365 * 4 +1)
이것이 내가 해결 한 해결책입니다.
def menor_edad_legal(birthday):
""" returns true if aged<18 in days """
try:
today = time.localtime()
fa_divuit_anys=date(year=today.tm_year-18, month=today.tm_mon, day=today.tm_mday)
if birthday>fa_divuit_anys:
return True
else:
return False
except Exception, ex_edad:
logging.error('Error menor de edad: %s' % ex_edad)
return True
이 스레드가 이미 죽었더라도 내가 직면 한이 같은 문제에 대한 해결책을 제안 할 수 있습니다. 여기 있습니다 (날짜는 dd-mm-yyyy 형식의 문자열입니다).
def validatedate(date):
parts = date.strip().split('-')
if len(parts) == 3 and False not in [x.isdigit() for x in parts]:
birth = datetime.date(int(parts[2]), int(parts[1]), int(parts[0]))
today = datetime.date.today()
b = (birth.year * 10000) + (birth.month * 100) + (birth.day)
t = (today.year * 10000) + (today.month * 100) + (today.day)
if (t - 18 * 10000) >= b:
return True
return False
이 함수는 두 날짜 사이의 연도 차이를 반환합니다 (ISO 형식의 문자열로 표시되지만 모든 형식으로 쉽게 수정할 수 있음).
import time
def years(earlydateiso, laterdateiso):
"""difference in years between two dates in ISO format"""
ed = time.strptime(earlydateiso, "%Y-%m-%d")
ld = time.strptime(laterdateiso, "%Y-%m-%d")
#switch dates if needed
if ld < ed:
ld, ed = ed, ld
res = ld[0] - ed [0]
if res > 0:
if ld[1]< ed[1]:
res -= 1
elif ld[1] == ed[1]:
if ld[2]< ed[2]:
res -= 1
return res
import datetime
def check_if_old_enough(years_needed, old_date):
limit_date = datetime.date(old_date.year + years_needed, old_date.month, old_date.day)
today = datetime.datetime.now().date()
old_enough = False
if limit_date <= today:
old_enough = True
return old_enough
def test_ages():
years_needed = 30
born_date_Logan = datetime.datetime(1988, 3, 5)
if check_if_old_enough(years_needed, born_date_Logan):
print("Logan is old enough")
else:
print("Logan is not old enough")
born_date_Jessica = datetime.datetime(1997, 3, 6)
if check_if_old_enough(years_needed, born_date_Jessica):
print("Jessica is old enough")
else:
print("Jessica is not old enough")
test_ages()
이것은 Carrousel 운영자가 Logan의 Run 영화에서 실행 한 코드입니다.)
나는이 질문을 보았고 Adams가 가장 도움이된다는 것을 알았습니다. https://stackoverflow.com/a/765862/2964689
그러나 그의 방법에 대한 파이썬 예제는 없었지만 여기에 내가 사용한 것이 있습니다.
입력 : 날짜 / 시간 객체
출력 : 전체 연도의 정수 연령
def age(birthday):
birthday = birthday.date()
today = date.today()
years = today.year - birthday.year
if (today.month < birthday.month or
(today.month == birthday.month and today.day < birthday.day)):
years = years - 1
return years
존 미 (John Mee)의 단순성에 대한 솔루션이 마음에 들었고, 윤년이 아닌 2 월 28 일 또는 3 월 1 일에 2 월 29 일에 태어난 사람들의 나이를 결정하는 방법에 대해서는 걱정하지 않습니다. 그러나 여기에 그의 코드가 약간 수정되었습니다 나는 불만을 해결한다고 생각합니다.
def age(dob):
import datetime
today = datetime.date.today()
age = today.year - dob.year
if ( today.month == dob.month == 2 and
today.day == 28 and dob.day == 29 ):
pass
elif today.month < dob.month or \
(today.month == dob.month and today.day < dob.day):
age -= 1
return age