Add n business days to a given date ignoring holidays and weekends in python

前端 未结 11 627
天涯浪人
天涯浪人 2020-12-05 10:32

I\'m trying to add n (integer) working days to a given date, the date addition has to avoid the holidays and weekends (it\'s not included in the working days)

相关标签:
11条回答
  • 2020-12-05 10:54

    If you don't mind using a 3rd party library then dateutil is handy

    from dateutil.rrule import *
    print "In 4 business days, it's", rrule(DAILY, byweekday=(MO,TU,WE,TH,FR))[4]
    

    You can also look at rruleset and using .exdate() to provide the holidays to skip those in the calculation, and optionally there's a cache option to avoid re-calculating that might be worth looking in to.

    0 讨论(0)
  • 2020-12-05 10:54

    I am using following code to handle business date delta. For holidays, you need to create your own list to skip.

    today = datetime.now()
    t_1 = today - BDay(1)
    t_5 = today - BDay(5)
    t_1_str = datetime.strftime(t_1,"%Y%m%d")
    
    
    
    0 讨论(0)
  • 2020-12-05 10:59

    Skipping weekends would be pretty easy doing something like this:

    import datetime
    def date_by_adding_business_days(from_date, add_days):
        business_days_to_add = add_days
        current_date = from_date
        while business_days_to_add > 0:
            current_date += datetime.timedelta(days=1)
            weekday = current_date.weekday()
            if weekday >= 5: # sunday = 6
                continue
            business_days_to_add -= 1
        return current_date
    
    #demo:
    print '10 business days from today:'
    print date_by_adding_business_days(datetime.date.today(), 10)
    

    The problem with holidays is that they vary a lot by country or even by region, religion, etc. You would need a list/set of holidays for your use case and then skip them in a similar way. A starting point may be the calendar feed that Apple publishes for iCal (in the ics format), the one for the US would be http://files.apple.com/calendars/US32Holidays.ics

    You could use the icalendar module to parse this.

    0 讨论(0)
  • 2020-12-05 11:00

    I know it does not handle holidays, but I found this solution more helpful because it is constant in time. It consists of counting the number of whole weeks, adding holidays is a little more complex. I hope it can help somebody :)

    def add_days(days):
        today = datetime.date.today()
        weekday = today.weekday() + ceil(days)
        complete_weeks = weekday // 7
        added_days = weekday + complete_weeks * 2
        return today + datetime.timedelta(days=added_days)
    
    0 讨论(0)
  • 2020-12-05 11:06

    There is no real shortcut to do this. Try this approach:

    1. Create a class which has a method skip(self, d) which returns True for dates that should be skipped.
    2. Create a dictionary in the class which contains all holidays as date objects. Don't use datetime or similar because the fractions of a day will kill you.
    3. Return True for any date that is in the dictionary or d.weekday() >= 5

    To add N days, use this method:

    def advance(d, days):
        delta = datetime.timedelta(1)
    
        for x in range(days):
            d = d + delta
            while holidayHelper.skip(d):
                d = d + delta
    
        return d
    
    0 讨论(0)
  • 2020-12-05 11:07

    This will take some work since there isn't any defined construct for holidays in any library (by my knowledge at least). You will need to create your own enumeration of those.

    Checking for weekend days is done easily by calling .weekday() < 6 on your datetime object.

    0 讨论(0)
提交回复
热议问题