Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Find the 1st business day and last business day of the previous month based on a date

I have a use case like this in Python: Find the 1st business day and last business day of the previous month based on a date. For example if date is 2024-06-10

first_business_day = '2024-05-01'
last_business_day = '2024-05-31'

I have tried like below

run_date = '2024-06-10'
from datetime import datetime, timedelta

d = datetime.strptime(run_date, '%Y-%m-%d').date()
previous_month_first_business_day = (d - timedelta(days=d.day)).replace(day=1).strftime("%Y-%m-%d")
previous_month_last_business_day = (d - timedelta(days=d.day)).strftime("%Y-%m-%d")

Result:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

previous_month_first_business_day = '2024-05-01'
previous_month_last_business_day = '2024-05-31'

This is working fine for month of May, but when I want the same result for June, then using the above I am getting:

previous_month_first_business_day = '2024-06-01' # This should be '2024-06-03'
previous_month_last_business_day = '2024-06-30' # This should be '2024-06-29'

What should I do to achieve the right result?

>Solution :

Take a look at the builtin calendar instead of just datetime

import calendar
import datetime

def month_start_end_work(date_src, fmt_date="%Y-%m-%d"):
    dt = datetime.datetime.strptime(date_src, fmt_date)

    # roll around January -> December
    month = 12 if dt.month == 1 else (dt.month - 1)
    year = dt.year if month != 12 else (dt.year - 1)

    # discover last day of last month
    for day in (31, 30, 29, 28):  # handle Feb cases
        try:  # already the correct year for leap
            month_start = calendar.weekday(year, month, day)
        except ValueError:  # day is out of range for month
            continue  # month has fewer days (always decreases)
        if month_start == calendar.SATURDAY:
            day -= 1
        elif month_start == calendar.SUNDAY:
            day -= 2
        break  # last day name to be used
    else:  # did not solve and break
        raise RuntimeError("BUG: impossible code path reached")
    day_last = (year, month, day)  # TODO may want to make a datetime.datetime
    
    # discover first day of last month
    day = 1  # all months begin at 1
    month_start = calendar.weekday(year, month, day)
    if month_start == calendar.SATURDAY:
        day += 2
    elif month_start == calendar.SUNDAY:
        day += 1
    day_first = (year, month, day)

    return day_first, day_last
>>> month_start_end_work("2024-06-10")
((2024, 5, 1), (2024, 5, 31))
>>> month_start_end_work("2024-07-10")
((2024, 6, 3), (2024, 6, 28))
>>> month_start_end_work("2022-01-01")
((2021, 12, 1), (2021, 12, 31))

If you have special days you know are days off (probably 6-12 annually), collect them into a list and just keep decrementing/incrementing for exact matches

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading