Check if it is the end of the month in python

Question:

I am writing code to take data from the last year. I want to round up the earlier date like so: If it is July 14 2015, I want data from August 1st 2014-July 14,2015

df = pd.read_csv('MyData.csv') 
df['recvd_dttm'] = pd.to_datetime(df['recvd_dttm'])
range_max = datetime.datetime.now() 
range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)
if datetime.datetime.now() == is_month_end:

# take slice with final week of data
df = df[(df['recvd_dttm'] >= range_min) & 
               (df['recvd_dttm'] <= range_max)]

My problem is that when it is July 31, 2015, my code goes to the end of the next month, essentially cutting out an entire month.

I am trying to make a for loop to fix this problem.

If it is the end of the month:

range_min = range_max - pd.tseries.offsets.DateOffset(years=1)

else:

range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)

How do I tell python to check for the end of the month? MonthEnd is only an offset function.

Asked By: jenryb

||

Answers:

Here is a short function to accomplish this. It requires the dateutil module so that you can do relative date math.

import datetime
from dateutil.relativedelta import relativedelta

def lastyear_period_start(current_date):
    last_year = current_date - relativedelta(months=11)
    return datetime.date(last_year.year, last_year.month, 1)

It can be utilized like so:

dates = [
    datetime.datetime(2010, 2, 27),
    datetime.datetime(2011, 2, 27),
    datetime.datetime(2012, 2, 27),
    datetime.datetime(2013, 2, 27),
    datetime.datetime(2014, 2, 27),
    datetime.datetime(2010, 7, 27),
    datetime.datetime(2011, 7, 27),
    datetime.datetime(2012, 7, 27),
    datetime.datetime(2013, 7, 27),
    datetime.datetime(2014, 7, 27),
    datetime.datetime(2015, 7, 14),
    datetime.datetime(2015, 7, 31),
    datetime.datetime(2011, 2, 28),
    datetime.datetime(2012, 2, 29),
    datetime.datetime(2013, 2, 28),
]

for d in dates:
    print d, lastyear_period_start(d)

This prints that following

2010-02-27 00:00:00 2009-03-01
2011-02-27 00:00:00 2010-03-01
2012-02-27 00:00:00 2011-03-01
2013-02-27 00:00:00 2012-03-01
2014-02-27 00:00:00 2013-03-01
2010-07-27 00:00:00 2009-08-01
2011-07-27 00:00:00 2010-08-01
2012-07-27 00:00:00 2011-08-01
2013-07-27 00:00:00 2012-08-01
2014-07-27 00:00:00 2013-08-01
2015-07-14 00:00:00 2014-08-01
2015-07-31 00:00:00 2014-08-01
2011-02-28 00:00:00 2010-03-01
2012-02-29 00:00:00 2011-03-01
2013-02-28 00:00:00 2012-03-01

In the function we’re doing two simple steps

  • last_year = current_date - relativedelta(months=11)

First we find out what the date was 11 months ago, based on the date passed to the function

  • return datetime.date(last_year.year, last_year.month, 1)

Then we return the first day of that month.

In the output above you can see this accounts for leap years as well.

Answered By: Andy

Alright, here’s what I did. Found the calendar module that BryanOakley suggested and made this loop. It checks the current day and checks if it is the same as the last day of the month, and chooses the range_min accordingly.

if datetime.datetime.now().day == calendar.monthrange(date.year, date.month)[1]:
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.DateOffset(days=1)
else:
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)
Answered By: jenryb

I simply would use the monthrange method of calendar module to find last day number of the month:

    def check_if_last_day_of_week(date):
        import datetime
        import calendar
        #  calendar.monthrange return a tuple (weekday of first day of the 
        #  month, number  
        #  of days in month)
        last_day_of_month = calendar.monthrange(date.year, date.month)[1]
        # here i check if date is last day of month
        if date == datetime.date(date.year, date.month, last_day_of_month):
            return True
        return False


>>> date = datetime.date(2018, 12, 31)
>>> check_if_last_day_of_week(date)
True
Answered By: Marco Di Cesare

We can avoid importing the calendar module with a short function that only leverages datetime.

If tomorrow’s month is not the same as today’s month, then that means today is the last day of the current month. We can check this programmatically with a short function such as

import datetime 
def end_of_month(dt):
    todays_month = dt.month
    tomorrows_month = (dt + datetime.timedelta(days=1)).month
    return tomorrows_month != todays_month

Now, for your specific use case:

now = datetime.datetime.now()
if end_of_month(now):
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1)
else: 
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1) +pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)
Answered By: Chris Greening
import datetime
def find_curr_month_end_date(curr_date):
    if(curr_date.month != 12):
        next_month_first_date= curr_date.replace(day=1).replace(month=curr_date.month+1)
    else:
        next_month_first_date= curr_date.replace(day=1).replace(month=1).replace(year=curr_date.year+1)

    curr_month_end_date = next_month_first_date - datetime.timedelta(days=1)

    return curr_month_end_date


curr_date = datetime.datetime.today() 
# or curr_date = datetime.datetime.strptime("2020-12-16","%Y-%m-%d")
curr_month_end_date = 
find_curr_month_end_date(curr_date)
Answered By: Manav Patadia

I was using Pandas and I did not want to include another library, so I used this to check whether is the last day of the month and last day of the year:

import pandas as pd

my_date = '31-12-2021'

current_data = pd.to_datetime(my_date, format='%d-%m-%Y')
current_month = current_data.month
current_year = current_data.year

following_day = current_data + pd.DateOffset(1)
tomorrows_month = following_day.month
tomorrows_year = following_day.year

is_last_day_of_month = True if tomorrows_month != current_month else False
is_last_day_of_year = True if tomorrows_year != current_year else False
Answered By: Matheus Torquato

Here’s a pure python approach that also takes into account leap years for february:

# total days in every month during non leap years
M_DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]


def isleap(year):
    """Return True for leap years, False for non-leap years."""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)


def days_in_month(year, month):
    """Returns total number of days in a month accounting for leap years."""
    return M_DAYS[month] + (month == 2 and isleap(year))


def is_monthend(ref_date):
    """Checks whether a date is also a monthend"""
    return ref_date.day == days_in_month(ref_date.year, ref_date.month)
Answered By: bravhek

If the next day is a different month, it means it is the last day of a month.

def check_if_last_day_of_month(to_date):
    delta = datetime.timedelta(days=1)
    next_day = to_date + delta
    if to_date.month != next_day.month:
        return True
    return False
Answered By: Chris
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.