如果我想在我的程序中添加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()
答案 0 :(得分:10)
The number of seconds in a year is not fixed。 Think you know how many days are in a year? Think again.
要执行句点(日历)算术,您可以使用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
答案 1 :(得分:9)
你不能只增加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)
答案 2 :(得分:1)
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)))