user487588
user487588

Reputation: 740

How would you get the xth weekday of a given month in python?

If I have a month (2017,5), and I would like to get the 10th weekday of that month -- is there a quick way to do it? Brute force, I know I could loop through every calendar day of time and create a massive mapping. But wondering if there is an easier way.

Sorry if this has been asked before! Can't seem to find a solution in python.

Upvotes: 0

Views: 711

Answers (2)

oz123
oz123

Reputation: 28858

Given a datetime.date object you can use the .isoweekday method to check the day of the week, all weekdays return values <=5 so:

def is_business_day(day):
    return day.isoweekday() < 5

You can use it like this to find all weekdays in a given month

In [29]: filter(lambda x: x[0] if x[1] else None, 
                [(d, is_business_day(datetime.date(2017,5,d))) 
                 for d in range(1,31)])
Out[29]: 
[(1, True),
 (2, True),
 (3, True),
 (4, True),
 (8, True),
 (9, True),
 (10, True),
 (11, True),
 (15, True),
 (16, True),
 (17, True),
 (18, True),
 (22, True),
 (23, True),
 (24, True),
 (25, True),
 (29, True),
 (30, True)]

This code isn't safe though. It does not check the boundaries of a month.

In [34]: filter(lambda x: x[1] if x[1] else None, 
                [(d, is_business_day(datetime.date(2017,2,d))) 
                  for d in range(1,31)])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-34-486d782346bd> in <module>()
----> 1 filter(lambda x: x[1] if x[1] else None, [(d, is_business_day(datetime.date(2017,2,d))) for d in range(1,31)])

ValueError: day is out of range for month

So you will have to make some more logic to figure the boundaries of months.

To figure out the boundaries of each month see How to find number of days in the current month

You can also improve the outputted formatted a bit:

In [43]: [d for d in range(1,31) if is_business_day(datetime.date(2017,5,d))]
Out[43]: [1, 2, 3, 4, 8, 9, 10, 11, 15, 16, 17, 18, 22, 23, 24, 25, 29, 30]

update, now the last comment of the OP is published, get the Xth business day:

Building on the latest list comperhansion, if x is the 9 business day:

In [6]: [d for d in range(1,31) if 
         is_business_day(datetime.date(2017,5,d))][9-1]
Out[6]: 15

In [7]: x=9

In [8]: [d for d in range(1,31) if 
         is_business_day(datetime.date(2017,5,d))][x-1]
Out[8]: 15

Upvotes: 2

Nicholas Smith
Nicholas Smith

Reputation: 11754

You want to implement a basic algorithm to solve it, there's quite a few but there's a very simple method listed on this wikipedia article: https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

Upvotes: 0

Related Questions