Python - Generate payroll payment dates

By xngo on August 3, 2019

Like most people, your paychecks come either biweekly or semimonthly. Regardless of your payout frequencies, money is transferred to your bank account on the 1st day of the month, the middle of the month or the last day of the month. But these days need to be a business day. If 1 of these days is not a business day, then the last previous business day is used. In this tutorial, I will show you how to generate payout dates using Python.

Get payout date on a business day

First, let's implement a method to return the payout date on a business day. If the payout date is on the weekends, then Friday is used. Here is the code.

import datetime
 
def getValidBusinessDate(dt):
    # For weekday(), Monday is 0 and Sunday is 6.
    days_to_substract = dt.weekday() - 4
    if days_to_substract > 0:
        d = dt - datetime.timedelta(days=days_to_substract)
        return d
    else:
        return dt
 
# Example using getValidBusinessDate(dt).
sunday_2019_06_30 = datetime.datetime(2019, 6, 30)
print( getValidBusinessDate(sunday_2019_06_30) ) # Output Friday: 2019-06-28

Get last day of the month

Now, let's implement a method to return the last day of the month. The easiest way to get the last day of the month is to use calendar.monthrange(year, month). Here is the code.

import datetime
def getLastDayOfMonth(dt):
    import calendar
    return calendar.monthrange(dt.year, dt.month)[1]
 
# Example using getLastDayOfMonth(dt)
any_date = datetime.datetime(2019, 7, 22)
print( getLastDayOfMonth(any_date) )    # Output: 31

Generate payout date for mid and last day of month

Finally, let's put everything together and generate payout date for the middle and the last day of the month for the whole year. Here is the final complete code.

import datetime
 
def getValidBusinessDate(dt):
    days_to_substract = dt.weekday() - 4
    if days_to_substract > 0:
        d = dt - datetime.timedelta(days=days_to_substract)
        return d
    else:
        return dt
 
 
def getLastDayOfMonth(dt):
    import calendar
    return calendar.monthrange(dt.year, dt.month)[1]
 
 
# Generate payout date for 2019.
any_year = datetime.datetime(2019, 7, 22)
 
for i in range(1, 13):
    mid_of_month      = any_year.replace(month=i).replace(day=15)
    last_day_of_month = any_year.replace(month=i).replace(day=getLastDayOfMonth(mid_of_month))
 
    print( getValidBusinessDate(mid_of_month), end=" | " )
    print( getValidBusinessDate(last_day_of_month) )

Output

2019-01-15 00:00:00 | 2019-01-31 00:00:00
2019-02-15 00:00:00 | 2019-02-28 00:00:00
2019-03-15 00:00:00 | 2019-03-29 00:00:00
2019-04-15 00:00:00 | 2019-04-30 00:00:00
2019-05-15 00:00:00 | 2019-05-31 00:00:00
2019-06-14 00:00:00 | 2019-06-28 00:00:00
2019-07-15 00:00:00 | 2019-07-31 00:00:00
2019-08-15 00:00:00 | 2019-08-30 00:00:00
2019-09-13 00:00:00 | 2019-09-30 00:00:00
2019-10-15 00:00:00 | 2019-10-31 00:00:00
2019-11-15 00:00:00 | 2019-11-29 00:00:00
2019-12-13 00:00:00 | 2019-12-31 00:00:00

About the author

Xuan Ngo is the founder of OpenWritings.net. He currently lives in Montreal, Canada. He loves to write about programming and open source subjects.