根据输入日期, 及相应月份调整, 返回调整后的日期:
例: 2017年7月15日前3个月是哪天
Answer = chg_month( datetime.date(2017, 7, 15), -3) = datetime.date(2017, 4, 15)
这个是第一个版本:
def chg_month(strdate, adnum):
y, m, d = strdate.year, strdate.month, strdate.day
y += (adnum + m -1) // 12
m = 1 + (adnum + m -1) % 12
return dt.date(y, m, d)
但是之后发现这个版本有一个问题, 假设参数为 2017年3月31日的前1个月, 那么最后 return dt.date(2017, 2, 31) 会引发以下错误(该错误来自datetime)
“ValueError: day is out of range for month”
针对这个异常,当时有两种考虑:
1-保留异常:如果我对月份调整后的日期有绝对精确的要求, 那么当2017年2月确实不存在31日的情况下, 应该让使用者明确知道, 而非忽略;
2-强制日期:对于任意输入的date中的d,全部按1计算,最后返回时还是以1为结果return;
3-调整日期:仅当发生ValueError异常时,通过while循环调整日期,直到不再抛出该异常。
最终,我个人考虑在满足业务需求的同时尽可能保留通用性,选择方案3-调整日期,重制后chg_month
def chg_month(strdate, adnum):
y, m, d = strdate.year, strdate.month, strdate.day
y += (adnum + m -1) // 12
m = 1 + (adnum + m -1) % 12
isdayoutrange = True
while isdayoutrange:
try:
dt.date(y, m, d)
except ValueError:
d -= 1
else:
isdayoutrange = False
return dt.date(y, m, d)
例: 2017年3月30日的前1个月
Answer = chg_month(datetime.date(2017, 3, 30), -1) = datetime.date(2017, 2, 28)