ある日付から何年も経過しているかどうかを確認する必要があります。現在私は持っtimedelta
ていますdatetime
モジュールおり、それを年に変換する方法がわかりません。
ある日付から何年も経過しているかどうかを確認する必要があります。現在私は持っtimedelta
ていますdatetime
モジュールおり、それを年に変換する方法がわかりません。
回答:
あなたはtimedelta
何年が経過したかを知るのに1 つ以上必要です。また、開始(または終了)日付も知っておく必要があります。(うるう年です)
あなたの最善の策はdateutil.relativedelta
オブジェクトを使用することですが、それはサードパーティのモジュールです。ある日付から数年経過した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()
)によって導入された差は、平均ジュリアン(365.25
)とグレゴリオ(365.2425
)年の差よりも大きくなります。。正しいアプローチは@Adam Rosenfieldの回答で
誰かが18歳かどうかを確認しようとしtimedelta
ている場合、うるう年のため、一部のエッジケースでは正しく使用できません。たとえば、2000年1月1日に生まれた人は、2018年1月1日に正確に6575日後(5うるう年を含む)になりますが、2001年1月1日に生まれた人は、1月1日に正確に6574日後に18歳になります。 2019(4うるう年を含む)。したがって、誰かが正確に6574日経過している場合、誕生日についての詳細情報を知らないと、17歳か18歳かを判断できません。
これを行う正しい方法は、2つの年を減算し、現在の月/日が誕生月/日の前にある場合は1を減算することにより、日付から直接年齢を計算することです。
まず、最も詳細なレベルでは、問題を正確に解決することはできません。年は長さが異なり、年の長さについて明確な「正しい選択」はありません。
とはいえ、「自然な」単位(おそらく数秒)の違いを取得し、その単位と年数の比率で割ります。例えば
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
あなたはそれがどれほど正確である必要がありますか? td.days / 365.25
あなたがうるう年を心配しているなら、あなたはあなたをかなり近づけます。
ここで言及されていないさらに別のサードパーティライブラリは、このタスクに使用できる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)
そして、はい、問題のこの単一のタスクの依存関係を追加することは、(Rick Copelandによって提案された)timeutilを使用する場合と比較しても、明らかにやり過ぎです。
結局あなたが持っているのは数学の問題です。4年ごとに1日余分な日がある場合、timedeltaを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
この関数は、2つの日付間の年数の差を返します(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()
これは、カルーセルオペレーターがローガンのラン映画で実行していたコードです;)
私はこの質問に出くわし、Adamsが最も役立つ答えを見つけましたhttps://stackoverflow.com/a/765862/2964689
しかし、彼の方法のpythonの例はありませんでしたが、これが私が最終的に使用したものです。
入力:日時オブジェクト
出力:整数年数
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