web-dev-qa-db-ja.com

Pythonでdatetime.dateオブジェクトに「3か月」を追加するにはどうすればよいですか?

Pythonの日付計算、どこでですか?

私はpythonアプリを数年にわたって3か月ごとに日付をプロットする必要があります。日付は年に4回だけ発生し、日付は毎年同じ日に発生することが重要です可能な限り、日付は可能な限り月の同じ日に発生し、日付はできる限り「3か月」離れていること(これは特にうるう年の移動目標です) )。残念ながら、datetime.timedeltaは月をサポートしていません!

Pythonでこの計算を行うための「標準的な」方法はありますか?

SQLの方法は?

最悪の事態が発生した場合、私はパントして、次のような答えを得るために、日付計算のためのNice組み込みサポートを持っているPostgreSQLに私のアプリに尋ねます:

# select ('2010-11-29'::date + interval '3 months')::date;
    date    
------------
 2011-02-28
(1 row)
25
Nathan

正確な日付または「より正確な」日付を探している場合は、おそらく dateutil をチェックアウトすることをお勧めします。

簡単な例:

>>> from dateutil.relativedelta import relativedelta
>>> import datetime
>>> TODAY = datetime.date.today()
>>> TODAY
datetime.date(2012, 3, 6)

ここで、TODAYに3か月を追加し、その日が正確に一致することを確認します(relativedelta(months=3)relativedelta(month=3)の動作が異なることに注意してください。これらの例では必ずmonthsを使用してください!).

>>> three_mon_rel = relativedelta(months=3)
>>> TODAY + three_mon_rel
datetime.date(2012, 6, 6)

そして、それは一年を通して一貫したままです。文字通り、3か月ごと、その日(何らかの理由でrelativedeltaを乗算し、datetime.dateオブジェクトに追加するとTypeErrorがスローされるため、追加を続けなければなりませんでした):

>>> TODAY + three_mon_rel + three_mon_rel
datetime.date(2012, 9, 6)
>>> TODAY + three_mon_rel + three_mon_rel + three_mon_rel
datetime.date(2012, 12, 6)
>>> TODAY + three_mon_rel + three_mon_rel + three_mon_rel + three_mon_rel
datetime.date(2013, 3, 6)

mVChr の推奨ソリューションは、間違いなく「十分」ですが、時間の経過とともにわずかにドリフトします。

>>> three_mon_timedelta = datetime.timedelta(days=3 * 365/12)
>>> TODAY + three_mon_timedelta
datetime.date(2012, 6, 5)

そして、1年の間、月の日はスライドし続けます:

>>> TODAY + three_mon_timedelta * 2
datetime.date(2012, 9, 4)
>>> TODAY + three_mon_timedelta * 3
datetime.date(2012, 12, 4)
>>> TODAY + three_mon_timedelta * 4
datetime.date(2013, 3, 5)
56
jathanism
import datetime

some_date = datetime.date.today()
three_months = datetime.timedelta(3*365/12)
print (some_date + three_months).isoformat()
# => '2012-06-01'

その後、新しい年ごとに元の日付に「正規化」します(2月29日を除く)

7
mVChr

ここに良い解決策があります http://www.voidspace.org.uk/python/weblog/Arch_d7_2012_02_25.shtml#e1235

標準的な方法で編集して申し訳ありません...

1
heinzderaugust

Python標準ライブラリ、つまりdateutilなどを使用せずに、 'February 31st'問題を解決する:

import datetime
import calendar

def add_months(date, months):
    months_count = date.month + months

    # Calculate the year
    year = date.year + int(months_count / 12)

    # Calculate the month
    month = (months_count % 12)
    if month == 0:
        month = 12

    # Calculate the day
    day = date.day
    last_day_of_month = calendar.monthrange(year, month)[1]
    if day > last_day_of_month:
        day = last_day_of_month

    new_date = datetime.date(year, month, day)
    return new_date

テスト:

>>>date = datetime.date(2018, 11, 30)

>>>print(date, add_months(date, 3))
(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

>>>print(date, add_months(date, 14))
(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))
1
David Ragazzi