몇 년 안에 파이썬 타임 델타
몇 년이 지난 지 몇 년이 지 났는지 확인해야합니다. 현재 모듈 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
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)))
일 수를 얻은 다음 몇 년 동안 365.2425 (평균 그레고리력 연도)로 나눕니다. 몇 달 동안 30.436875 (평균 그레고리력 달)로 나눕니다.
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)
First parameter is expected to be a DateTime
instance.
To convert ordinary datetime
to DateTime
you could use this for 1 second precision):
def DT_from_dt_s(t):
return DT.DateTimeFromTicks(time.mktime(t.timetuple()))
or this for 1 microsecond precision:
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)
And yes, adding the dependency for this single task in question would definitely be an overkill compared even with using timeutil (suggested by Rick Copeland).
In the end what you have is a maths issue. If every 4 years we have an extra day lets then dived the timedelta in days, not by 365 but 365*4 + 1, that would give you the amount of 4 years. Then divide it again by 4. timedelta / ((365*4) +1) / 4 = timedelta * 4 / (365*4 +1)
This is the solution I worked out, I hope can help ;-)
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
How exact do you need it to be? td.days / 365.25
will get you pretty close, if you're worried about leap years.
Even though this thread is already dead, might i suggest a working solution for this very same problem i was facing. Here it is (date is a string in the format 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
this function returns the difference in years between two dates (taken as strings in ISO format, but it can easily modified to take in any format)
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
I'll suggest Pyfdate
What is pyfdate?
Given Python's goal to be a powerful and easy-to-use scripting language, its features for working with dates and times are not as user-friendly as they should be. The purpose of pyfdate is to remedy that situation by providing features for working with dates and times that are as powerful and easy-to-use as the rest of Python.
the tutorial
Well, question seems rather easy. You need to check the number of 'full' years, and only if it's equal to 18 you need to bother with months and days. The edge case is: endDate.year - startDate.year == 18
and it splits to two cases: startDate.month != endDate.month
and startDate.month == endDate.month
, when you just have to check days:
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
It's still more than one-liner-lambda, but it's still pretty short, and seems quick in execution.
참고URL : https://stackoverflow.com/questions/765797/python-timedelta-in-years
'IT박스' 카테고리의 다른 글
Cocoa 및 Objective-C를 사용한 참조 횟수 이해 (0) | 2020.07.11 |
---|---|
데이터 바인딩을 통해 WPF 하이퍼 링크의 텍스트를 설정하려면 어떻게해야합니까? (0) | 2020.07.11 |
PHP 치명적 오류 : 객체 컨텍스트에 없을 때 $ this 사용 (0) | 2020.07.11 |
앞에 다른 것이 없으면 일치하는 정규 표현식 (0) | 2020.07.11 |
WebView 및 HTML5 (0) | 2020.07.11 |