10

I am trying to write a Python script that will calculate how many business days are in the current month. For instance if month = August then businessDays = 22.

Here is my code for discovering the month:

def numToMonth( num ): months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] return str(months[ num - 1 ]) 

This code works fine, and I could hard code another function to match the month with how many days that month should contain...but this does not help me with business days.

Any help? I'm used to C, C++ so please don't bash my Python "skills".

Edit: I cannot install any extra libraries or modules on my machine, so please post answers using default Python modules. (Python 2.7, datetime etc.) Also, my PC has Windows 7 OS.

10
  • 1
    This looks like relevant: stackoverflow.com/questions/2224742/business-days-in-python Commented Aug 14, 2013 at 13:31
  • Thanks for the link! I viewed that question, but I'm not allowed to install extra libraries on my machine. I will edit my question to reflect this. Commented Aug 14, 2013 at 13:34
  • Should your code process holidays correctly? Commented Aug 14, 2013 at 13:35
  • It wouldn't hurt, but that is not a priority. I can hard code Holidays into the code depending on the month. My workplace is UK related so their holidays are strange. Commented Aug 14, 2013 at 13:37
  • 1
    And should it calculate number of days for current year? Commented Aug 14, 2013 at 13:43

8 Answers 8

15

This is a long-winded way, but at least it works and doesn't require anything other than the standard modules.

import datetime now = datetime.datetime.now() holidays = {datetime.date(now.year, 8, 14)} # you can add more here businessdays = 0 for i in range(1, 32): try: thisdate = datetime.date(now.year, now.month, i) except(ValueError): break if thisdate.weekday() < 5 and thisdate not in holidays: # Monday == 0, Sunday == 6 businessdays += 1 print businessdays 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help! I had to modify the code a little.. (Your indentation was strange) But it works. Thanks again.
No problem. In what way was my indentation strange? The code above only catches PEP8 errors for the long line and the comment style.
looks like a hack but I would have done like that :) and it works. So thanks. Small remark: why hardcoding the year? to get a budget to ask your bosses to reopen the program in 2014 for heavy maintenance ? :)
@Jean-FrançoisFabre In my country (South Africa) most holidays are not on exactly specified dates every year because the date they are observed changes to the following Monday if they fall on a weekend. So I would actually imagine you will have a yearly calendar for holidays which will be different every year. ;-)
10

I would simply use built-in module calendar:

import calendar weekday_count = 0 cal = calendar.Calendar() for week in cal.monthdayscalendar(2013, 8): for i, day in enumerate(week): # not this month's day or a weekend if day == 0 or i >= 5: continue # or some other control if desired... weekday_count += 1 print weekday_count 

that's it.

1 Comment

Does calendar start with Monday and not Sunday?
7

I would like to add my answer.

I'm using Calendar, list comprehension, and length to count how many days is the working day a particular month.

Here is my code:

#!/bin/env python import calendar import datetime now = datetime.datetime.now() cal = calendar.Calendar() working_days = len([x for x in cal.itermonthdays2(now.year, now.month) if x[0] !=0 and x[1] < 5]) print "Total working days this month: " + str(working_days) 

Comments

1

I stole this from Sharuzzaman's solution and added a dict for holidays and turned it into a function:

import calendar cal = calendar.Calendar() def get_wdim(year,month): working_days = len([x for x in cal.itermonthdays2(year, month) if x[0] !=0 and x[1] < 5]) holidays = { 1:1, 2:1, 4:1, 5:1, 7:1, 9:1, 10:1, 11:4, 12:1 } return int(working_days) - holidays.get(month,0) wdim2022 = [get_wdim(2022,x) for x in list(range(1,13)) ] 

Comments

0

UPDATE: OP can't use any external libraries. Then you will have to build some tables based on determining the day of the week from the calendar.

The formula is d + m + y + y/4 + (c mod 7), where: d is the day of the month, m is the month's number in the months table, y is the last two digits of the year, and c is the century number.

It's tedious but not impossible!

ORIG answer: It's quite tedious to code yourself, because August 01, 2013 and August 01, 2012 are not necessarily the same day of the week. I'd start with the 'date' class in python (details here

from datetime import date datetime.date(2002, 3, 11) t = d.timetuple() for i in t: print i 

In particular, check out the 'datetime.weekday()' function.

Comments

0

This is relatively simple, just break it down into steps:

  1. You need to be able to loop through the days in a month.
  2. You need to be able to determine the day of a week that any given date falls on. Wikipedia lists some methods.
  3. Then you need only flag days of the week as business days or not.

Combine these steps and you'll have a working method.

1 Comment

Thanks for encouraging me to do more research, but I was looking for a method already built in to Python. If it doesn't exist, I will post whatever algorithm I create as an answer.
0

You could take a look at datetime.datetime.dayofweek() but if you are not allowed to use an external library then you need to:

  1. pick a date that you know the day of week of - best if it is a Monday
  2. come up with a formulae for the number of days since then that the first of a given month is.
  3. for each of the days in the month the (number of days since your day) % 7 in [5, 6] is a weekend.

Comments

0

Acknowledging the OP stated external libraries could not be used, given the ranking of the question in searches (together with the fact this wasnt stated in the title), I figured I'd share a pandas solution which provides a solution spanning multiple months, with results presented in a df.

 import pandas as pd business_days = pd.date_range(start, end, freq='B') pd.DataFrame(index=business_days, data=[1] * len(business_days)).resample('M').sum() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.