How to calculate a date from a different date with a given number of business days

I need to calculate a date (year, month, day) that is (for example) 18 business days ago from a different date. That would be enough to rule out just the weekend.

Example: I have the date 2009-08-21 and the number of 18 business days as a parameter, and the correct answer should be 2009-07-27.

thanks for any help

+2


source to share


8 answers


I assume you are using datetime, but this should work (date is date, days is integer):

def goback(date, days):
    delta = datetime.timedelta( days=days + 2*(days//5) )
    if date.weekday() == 5:
        delta += datetime.timedelta(days=1)
    elif date.weekday() == 6:
        delta += datetime.timedelta(days=2)
    else:
        leftover = date.weekday() - days % 5
        if leftover < 0: 
            delta += datetime.timedelta(days=2)
    return date - delta

      



Please note that the example in your description is not correct, I think. 18 business days to 21st - 28th.

0


source


I suggest taking a look at http://docs.python.org/library/calendar.html with it you can easily figure out what day of the week a certain date is and then you can calculate back - given the weekend



+2


source


Here's one way to do it. Note (1) you are not saying what you expect if the start date is not a business day. (2) Your example is wrong.

C:\junk\so>type workdays.py
import datetime

def add_workdays(adate, nworkdays):
    if nworkdays < 0:
        incr = -1
        nworkdays = - nworkdays
    else:
        incr = 1
    delta_weeks, delta_days = divmod(nworkdays, 5)
    one_day = datetime.timedelta(days=incr)
    if delta_weeks:
        wdate = adate + one_day * 7 * delta_weeks
    else:
        wdate = adate
    while delta_days:
        wdate += one_day
        if wdate.weekday() < 5: # Mon-Fri
            delta_days -= 1
    return wdate

if __name__ == "__main__":
    start = datetime.date(2009, 8, 21)
    for i in range(10, -19, -1):
        end = add_workdays(start, i)
        print "%3d %s" % (i, end.strftime("%a %Y-%m-%d"))

C:\junk\so>\python26\python workdays.py
 10 Fri 2009-09-04
  9 Thu 2009-09-03
  8 Wed 2009-09-02
  7 Tue 2009-09-01
  6 Mon 2009-08-31
  5 Fri 2009-08-28
  4 Thu 2009-08-27
  3 Wed 2009-08-26
  2 Tue 2009-08-25
  1 Mon 2009-08-24
  0 Fri 2009-08-21
 -1 Thu 2009-08-20
 -2 Wed 2009-08-19
 -3 Tue 2009-08-18
 -4 Mon 2009-08-17
 -5 Fri 2009-08-14
 -6 Thu 2009-08-13
 -7 Wed 2009-08-12
 -8 Tue 2009-08-11
 -9 Mon 2009-08-10
-10 Fri 2009-08-07
-11 Thu 2009-08-06
-12 Wed 2009-08-05
-13 Tue 2009-08-04
-14 Mon 2009-08-03
-15 Fri 2009-07-31
-16 Thu 2009-07-30
-17 Wed 2009-07-29
-18 Tue 2009-07-28

C:\junk\so>

      

+2


source


I recommend using scikits time series with "business" frequency. You can download this great python package here:

http://pytseries.sourceforge.net/

Then you can write something like

import datetime
import scikits.timeseries as TS
workDay1 = TS.Date(freq='B', datetime=datetime.datetime(2009,8,21))
workDay2 = workDay1 - 7
asDatetime = workDay2.datetime

      

+1


source


If you are using pandas you can do this easily:

from pandas.tseries.offsets import BDay
import datetime

datetime.datetime(2009, 8, 21) - 18 * BDay()

      

+1


source


I would probably just go through the days checking if the day is Mon-Fri.
Not as effective, but easier to get right.

0


source


If you need to count holidays as non-working days at some point, you will need to work out Easter / Good Friday, which is best left to the library call:

>>> from dateutil import easter
>>> easter.easter(2009)
datetime.date(2009, 4, 12)


Other major holidays are relatively simple: they either meet the same date every year, or fall on a consecutive day of the week every other month. You can check out period.py ( http://www.medsch.wisc.edu/~annis/creations/period.py.html ), which offers the is_holiday () method, although it does require customization.

The NYSE Stock Market Holidays provide a reasonable default vacation schedule for the United States.

0


source


My wife Anna has a recipe for this in the second edition. from the Python Cookbook - you can read it on the web with this google book url search , it starts with p. 122. Recipe 3.5 is weekdays versus weekends; the very next recipe, 3.6, adds attention to the holidays, but unfortunately it can only be partially read on the internet when searching for books on google (I've seen a lot of pirated copies of our book advertised as free downloads but don't have friendly URLs) ...

These recipes are especially close and dear to our hearts because they mostly relate to how we reconnected (on the Internet) through the years we lost each other. Anna was looking for help improving them as they needed their functionality in the workplace, I suggested ... 20 months later we were married; -).

0


source







All Articles