web-dev-qa-db-ja.com

python

プログラムに100年を追加したいのに、なぜ間違った日付が表示されるのですか?

import datetime
stringDate= "January 10, 1920"
dateObject= datetime.datetime.strptime(stringDate, "%B %d, %Y")
endDate= dateObject+datetime.timedelta(days=100*365)
print dateObject.date()
print endDate.date()
9
ismail khan

1年の秒数は固定されていません1年に何日あるか知っていると思いますか?もう一度考えてください。

期間(カレンダー)演算を実行するには、 _dateutil.relativedelta_ を使用できます。

_#!/usr/bin/env python
from datetime import date
from dateutil.relativedelta import relativedelta # $ pip install python-dateutil

print(date(1920, 1, 10) + relativedelta(years=+100))
# -> 2020-01-10
_

d.replace(year=d.year + 100)が失敗する理由を理解するには、次のことを考慮してください。

_print(date(2000, 2, 29) + relativedelta(years=+100))
2100-02-28
_

_2100_はうるう年ではなく、_2000_はうるう年であることに注意してください。

追加する単位が年のみの場合は、stdlibのみを使用して実装できます。

_from calendar import isleap

def add_years(d, years):
    new_year = d.year + years
    try:
        return d.replace(year=new_year)
    except ValueError:
        if (d.month == 2 and d.day == 29 and # leap day
            isleap(d.year) and not isleap(new_year)):
            return d.replace(year=new_year, day=28)
        raise
_

例:

_from datetime import date

print(add_years(date(1920, 1, 10), 100))
# -> 2020-01-10
print(add_years(date(2000, 2, 29), 100))
# -> 2100-02-28
print(add_years(date(2000, 2, 29), 4))
# -> 2004-02-29
_
12
jfs

100 * 365日を追加することはできません。これは、その期間に366日といううるう年があるためです。あなたの100年のスパンにわたってあなたは25日を逃しています。

datetime.replace() method を使用する方が良いです:

endDate = dateObject.replace(year=dateObject.year + 100)

追加する年数によっては無効な日付になるため、うるう年の2月29日はまだ失敗する可能性があります。その場合は2月28日に戻るか、3月31日を使用できます。スローされた例外を処理し、選択した置換に切り替えます。

years = 100
try:
    endDate = dateObject.replace(year=dateObject.year + years)
except ValueError::
    # Leap day in a leap year, move date to February 28th
    endDate = dateObject.replace(year=dateObject.year + years, day=28)

デモ:

>>> import datetime
>>> dateObject = datetime.datetime(1920, 1, 10, 0, 0)
>>> dateObject.replace(year=dateObject.year + 100)
datetime.datetime(2020, 1, 10, 0, 0)
10
Martijn Pieters

男3mktime

Cをやったことがある人なら誰でも答えを知っています。

mktimeは、オーバーフローした値を次に大きい単位に自動的に追加します。日時に戻す必要があります。

たとえば、2019-07-40でフィードすると、2019-08-09に変換されます。

>>> datetime.fromtimestamp(mktime((2019, 7, 40, 0, 0, 0, 0, 0, 0)))
datetime.datetime(2019, 8, 9, 0, 0)

または2019-03-(-1)は2019-02-27に変換されます:

>>> datetime.fromtimestamp(mktime((2019, 3, -1, 0, 0, 0, 0, 0, 0)))
datetime.datetime(2019, 2, 27, 0, 0)

したがって、古い日付を取得して、好きなものを追加するだけです。

now = datetime.datetime.now()
hundred_days_later = datetime.datetime.fromtimestamp(mktime((now.year, now.month, now.day + 100, now.hour, now.minute, now.second, 0, 0, 0)))
1
Alexander Simon