나는 어떤 날짜 이후 몇 년 동안 있었는지 확인해야합니다. 현재 을 모듈에서 가져 왔으며 수년으로 변환하는 방법을 모르겠습니다.파이썬 timedelta 년
답변
몇 년이 지났는지 알려면 timedelta
이상이 필요합니다. 당신은 또한 시작 (또는 결말) 날짜를 알아야합니다. (윤년 일입니다.)
가장 좋은 방법은 dateutil.relativedelta
object을 사용하는 것이지만 타사 모듈을 사용하는 것이 가장 좋습니다. 당신이 어떤 일로부터 n
년했다 datetime
이 (지금을 디폴트) 알고 싶은 경우에, 당신은 다음 ::
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)
오히려 표준 라이브러리와 스틱 싶은 경우는, 답이있다 할 수있다 좀 더 복잡한 ::
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 일을 기준으로 추측 할 수 다음 위 :이 스레드가 이미 죽었 비록
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
그레고리력에 대한 400 년 예외를 고려한 365.2425 (365.25 대신)로 완전히 정확할 수 있습니다. – brianary
영국과 홍콩과 같은 국가에서는 3 월 1 일에 윤년이 "만료"되기 때문에 함수가 법적으로 중단됩니다. – antihero
@brianary : 로컬 표준 시간대 ('datetime.now()'에 의해 소개 된 차이)가 * 평균 * 줄리안 ('365.25')과 그레고리오 (' '365.2425') 년.] (http://stackoverflow.com/a/32658742/4279). 올바른 접근법은 [@Adam Rosenfield의 대답] (http://stackoverflow.com/a/765862/4279) – jfs
먼저 가장 상세한 수준에서 문제를 정확하게 해결할 수 없습니다. 년의 길이는 다양하며, 연도 길이에 대한 명확한 "올바른 선택"이 없습니다.
그렇다면 단위가 "자연스러운"단위 (아마 초 단위)가 무엇이든간에 그 차이를 얻고 그와 년 사이의 비율로 나눕니다. 예 :
delta_in_days/(365.25)
delta_in_seconds/(365.25*24*60*60)
... 또는 무엇이든간에. 그들이 몇 해보다 잘 정의되어 있지 않기 때문에 몇 달간 떨어져있어 라.
누군가가 18 세인지 확인하려는 경우 윤년으로 인해 일부 가장자리의 경우에는 timedelta
을 올바르게 사용하지 않습니다. 예를 들어 2000 년 1 월 1 일에 태어난 사람은 2018 년 1 월 1 일에 6575 일 후에 정확히 18 세가되며 (5 윤년 포함), 2001 년 1 월 1 일에 태어난 사람은 정확히 1 월 1 일에 정확히 6574 일 후에 18 세가됩니다. 2019 년 (4 윤년 포함). 따라서 누군가가 정확히 6574 일 된 경우, 자신의 생년월일에 대해 더 많은 정보를 알지 못해서 17 세 또는 18 세인지를 판단 할 수 없습니다.
올바른 방법은 날짜를 기준으로 나이를 직접 계산 한 다음 2 년을 빼고 현재 월/일이 출생 월/일보다 앞에있는 경우 1을 뺍니다.
과 관련된 두 형식의 날짜 : [Age from python in birthday] (http : // stackoverflow. com/a/9754466/4279) – jfs
정의 yearsago
기능 중 하나를 사용하여 체크, 나는 제안 할 수 내가 직면하고 있던이 바로 그 문제에 대한 해결책을 제시한다.여기 (날짜의 형식은 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
글쎄, 질문은 쉬운 것처럼 보입니다. '전체'연도의 수를 확인해야하며, 18에 해당하는 경우에만 월 및 일로 고생해야합니다. endDate.year - startDate.year == 18
과 두 건으로 분할 : 가장자리 케이스는 당신이 며칠 확인해야 할 때, startDate.month != endDate.month
및 startDate.month == endDate.month
:
def isOfAge(birthDate, age=18):
endDate = date.today()
years = endDate.year - birthDate.year
if years == age:
return (birthDate.month < endDate.month or
(birthDate.month == endDate.month and birthDate.day < endDate.day))
return years > age
그것은 여전히 1 이상 라이너 람다하지만 여전히 꽤 짧은, 그리고 보인다 빠른 실행.
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
2 월 29 일에 태어난 사람은 다음 2 월 28 일에 1 세가 된 것으로 간주됩니다. –
"오늘 이후의 생일"에서 "오늘 전의 생일"로 반올림하여 29 세에 태어난 인구의 0.08 %를 수용하도록 수정되었습니다. 그게 해결 되니? –
아니요, 해결되지 않습니다. 테스트를 믿지 않습니까? –
또 다른 제 3 자 lib 디렉토리 mxDateTime (모두 파이썬 datetime
및 제 3 자 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
것으로 예상된다. 1 마이크로 초 정밀도
def DT_from_dt_s(t):
return DT.DateTimeFromTicks(time.mktime(t.timetuple()))
나이 :
당신이) 일초 정밀이를 사용할 수있는 일반 datetime
DateTime
로 변환하는
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가 제안한)을 사용하는 것보다 과잉 공격이 될 것입니다.
일 수를 구한 다음 연도는 365.2425 (평균 그레고리력 연도)로 나눕니다. 몇 달 동안 30.436875 (평균 그레고리력 달)로 나눕니다.
마지막으로 가지고있는 것은 수학 문제입니다. 매 4 년마다 우리가 여분의 하루를 갖게되면, 365, 365 * 4 + 1이 아니라 4 일의 양을 줄 수있는 일을 시간표로 계산할 수 있습니다. 그런 다음 다시 4로 나눕니다. timedelta/((365 * 4) + 1)/4 = timedelta * 4/(365 * 4 일)
년을 100으로 나눌 수있는 경우 윤년 문제는 적용되지 않습니다. 그래서 2000 년의 경우 - 그것은 4로 나눌 수 있기 때문에 도약해야하지만 ... - 백으로 나눌 수 있기 때문에 도약해서는 안되지만 ... - 400으로 나눌 수 있으므로 실제로 윤년이었습니다. 1900의 경우 : - 4로 나눌 수 있으므로 도약해야합니다. - 100으로 나눌 수 있으므로 뜀질해서는 안됩니다. - 400으로 나눌 수 없으므로이 규칙이 적용되지 않습니다. 1900 년은 윤년이 아니 었습니다. – Jblasco
이 내가 밖으로 일이 솔루션은 내가 ;-)
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
을 도울 수있는 희망입니다
여기에 생일을 계산하는 업데이트 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)))
dob가 2 월 29 일이고 현재 연도가 윤년이 아닐 때 이것은 중단됩니다. –
이 응답을 참조하십시오 http://stackoverflow.com/a/9754466/65387을 – Adam
관련 : [년을 변환하는 방법을 제 ] (http://stackoverflow.com/a/32658742/4279) – jfs