6

I am getting the number of days until the next "billing cycle" (for example) which starts on the nth day of the month:

from dateutil.relativedelta import relativedelta

dt = datetime.utcnow() + relativedelta(months=1,day=schedule.cycle_start)
days_till_next_cycle = dt - datetime.utcnow()

Where schedule.cycle_start is going to be something like 2 for the second day of the month.

This works... But:

How do I find the number of weekdays in that timedelta.

I took a look at https://pypi.python.org/pypi/BusinessHours/ and could not find any documentation.

I also saw this: Business days in Python which linked me to the link above and rolling my own. It's also been 4 years since that post and I was hoping there might be a simpler way?

Community
  • 1
  • 1
Johnston
  • 20,196
  • 18
  • 72
  • 121

2 Answers2

8

With rrule I was able get the following using the dt definition from above:

    from dateutil.rrule import *
    number_weekdays = rrule(WEEKLY, byweekday=(MO,TU,WE,TH,FR), dtstart=datetime.utcnow(),until=dt).count()
Rob Parker
  • 503
  • 4
  • 10
  • Nice answer! Btw, `rrule`s also have a [count method](http://labix.org/python-dateutil#head-cf004ee9a75592797e076752b2a889c10f445418). – unutbu Jan 16 '14 at 03:41
  • Very cool! If say I wanted to only calculate by `Mo`,`Tu`,`Th`,`Fr` could I just leave out `we` out of the tuple? And it would just work? (If for example the business was not open on wednesdays?) – Johnston Jan 16 '14 at 03:48
  • @RobParker I believe the answer for my comment above is yes, as I just tried it and it worked. Just double checking though. – Johnston Jan 16 '14 at 03:58
2

Here a simple function that compute the number of business days between 2 dates:

def business_days(since, until):
    since_isoweekday = since.isoweekday() + 1
    return len([x for x in range(since_isoweekday,
                                 since_isoweekday + (until - since).days)
                if x % 7 not in [0, 6]])

not in [0, 6] stands for saturday and sunday.

Some tests:

>>> since = datetime.datetime(2014, 6, 2)
>>> until = datetime.datetime(2014, 6, 30)
>>> business_days(since, until)
20
>>> since = datetime.datetime(2014, 6, 25)
>>> until = datetime.datetime(2014, 7, 4)
>>> business_days(since, until)
7
Stan
  • 8,710
  • 2
  • 29
  • 31