如果我在程序中想加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()
如果我在程序中想加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()
如果要进行周期(日历)运算,可以使用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
你不能简单地将100 * 365天相加,因为该时间段中有366天的闰年。在你的100年中,你会少25天。
最好在这里使用 datetime.replace()
方法:
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)
man 3 mktime
任何做过 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)))
date = "2003-07-01"
date_start = Timestamp(date)
date_end = Timestamp(date_start.year+3, date_start.month, date_start.day)
date_end
# Out:
Timestamp('2006-07-01 00:00:00')
若要将日期增加40天,请使用Timedelta(它不支持年份,否则我们可以在最后一个问题中使用它):
date_end = date_start + Timedelta(40, unit="days")
date_end
# Out:
Timestamp('2003-08-10 00:00:00')