如何在python中修复月末的日期函数?

时间:2016-11-19 12:21:50

标签: python datetime

此函数应该为from_date添加天数,添加n天数(add_days)而不计算周末和假期(从我的列表中),但如果from_date日将超过月份,则在月末停止这个月。 例如,如果我打印:

 print date_by_adding_business_days(datetime.date(2015,01,22), 3,Holidays)

将打印:2015-01-27,这很好,也适用于假期。

如果我会尝试:

 print date_by_adding_business_days(datetime.date(2015,01,22), 12,Holidays)

它会在我想要的月底停止:2015-01-30

但如果我的from_date将是:

print date_by_adding_business_days(datetime.date(2015,01,30), 12,Holidays)

它将返回None,而不是我需要的2015-01-30

我的问题是当我的from_date是月末时,我的函数将返回None。如果我的from_date在月底(我不想要添加多少天),我想要返回确切的from_date。 这是我的功能:

def date_by_adding_business_days(from_date, add_days,holidays):
    business_days_to_add = add_days
    current_date = from_date
    result = None
    _, days_in_month = calendar.monthrange(current_date.year, current_date.month)
    while business_days_to_add > 0 and current_date.day < days_in_month:
        current_date += datetime.timedelta(days=1)
        weekday = current_date.weekday()
        if weekday >= 5:
            continue
        if current_date in holidays:
            continue
        business_days_to_add -= 1
        result = current_date
    return result
Holidays =[datetime.date(2015,10,14),datetime.date(2015,10,15)]
print date_by_adding_business_days(datetime.date(2015,01,30), 12,Holidays)

Calendar

1 个答案:

答案 0 :(得分:0)

您的代码不会检查开始日期。

>>> # The last day in the month is not a business day so it should returns `2015-01-30`
... print date_by_adding_business_days(datetime.date(2015, 01, 30), 12, Holidays)
None
>>> # The last day in the month is not a business day so it should returns `None`
... print date_by_adding_business_days(datetime.date(2015, 01, 31), 12, Holidays)
None
>>> # The last day in the month is a business day so it should returns `2016-10-31`
... print date_by_adding_business_days(datetime.date(2016, 10, 30), 12, Holidays)
2016-10-31
>>> # The last day in the month is a business day so it should returns `2016-10-31
... print date_by_adding_business_days(datetime.date(2016, 10, 31), 12, Holidays)
None
>>> # Last two days in the month is not business days so it should returns `None`
... print date_by_adding_business_days(datetime.date(2016, 07, 30), 12, Holidays)
None

解决方案result = current_date不起作用,因为它总是会返回开始日期,尽管没有工作日。

>>> # The last day in the month is not a business day so it should returns `2015-01-30`
... print date_by_adding_business_days(datetime.date(2015, 01, 30), 12, Holidays)
2015-01-30
>>> # The last day in the month is not a business day so it should returns `None`
... print date_by_adding_business_days(datetime.date(2015, 01, 31), 12, Holidays)
2015-01-31
>>> # The last day in the month is a business day so it should returns `2016-10-31`
... print date_by_adding_business_days(datetime.date(2016, 10, 30), 12, Holidays)
2016-10-31
>>> # The last day in the month is a business day so it should returns `2016-10-31
... print date_by_adding_business_days(datetime.date(2016, 10, 31), 12, Holidays)
2016-10-31
>>> # Last two days in the month is not business days so it should returns `None`
... print date_by_adding_business_days(datetime.date(2016, 07, 30), 12, Holidays)
2016-07-30

我已经重写了你的代码,所以检查开始日期,并在没有结果的情况下返回none。

def date_by_adding_business_days(from_date, add_days, holidays):
    business_days_to_add = add_days
    current_date = from_date
    result = None
    _, days_in_month = calendar.monthrange(current_date.year, current_date.month)
    while business_days_to_add > 0:
        if current_date.weekday() < 5 and current_date not in holidays:
            business_days_to_add -= 1
            result = current_date
        if current_date.day == days_in_month:
            break
        current_date += datetime.timedelta(days=1)
    return result

-

>>> # The last day in the month is a not business day so it should returns `2015-01-30`
... print date_by_adding_business_days(datetime.date(2015, 01, 30), 12, Holidays)
2015-01-30
>>> # The last day in the month is not a business day so it should returns `None`
... print date_by_adding_business_days(datetime.date(2015, 01, 31), 12, Holidays)
None
>>> # The last day in the month is a business day so it should returns `2016-10-31`
... print date_by_adding_business_days(datetime.date(2016, 10, 30), 12, Holidays)
2016-10-31
>>> # The last day in the month is a business day so it should returns `2016-10-31
... print date_by_adding_business_days(datetime.date(2016, 10, 31), 12, Holidays)
2016-10-31
>>> # Last two days in the month is not business days so it should returns `None`
... print date_by_adding_business_days(datetime.date(2016, 07, 30), 12, Holidays)
None