Get the last day of the month
Asked Answered
D

45

902

Is there a way using Python's standard library to easily determine (i.e. one function call) the last day of a given month?

If the standard library doesn't support that, does the dateutil package support this?

Daemon answered 4/9, 2008 at 0:54 Comment(0)
H
1480

calendar.monthrange provides this information:

calendar.monthrange(year, month)
    Returns weekday of first day of the month and number of days in month, for the specified year and month.

>>> import calendar
>>> calendar.monthrange(2002, 1)
(1, 31)
>>> calendar.monthrange(2008, 2)  # leap years are handled correctly
(4, 29)
>>> calendar.monthrange(2100, 2)  # years divisible by 100 but not 400 aren't leap years
(0, 28)

so:

calendar.monthrange(year, month)[1]

seems like the simplest way to go.

Healey answered 4/9, 2008 at 12:44 Comment(4)
I can't be the only one thinking monthrange is a confusing name. You would think it would return (first_day, last_day), not (week_day_of_first_day, number_of_days)Muscle
first_day wouldn't be especially useful since it would always be 1. But I agree, week_day_of_first_day seems unrelated to "month range".Eadwine
For those who didn't know: calendar is in the standard library.Antetype
knowing the day of the week of the first day does allow you to calculate how many weekdays are in the month using only basic arithmeticExample
D
282

If you don't want to import the calendar module, a simple two-step function can also be:

import datetime

def last_day_of_month(any_day):
    # The day 28 exists in every month. 4 days later, it's always next month
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
    # subtracting the number of the current day brings us back one month
    return next_month - datetime.timedelta(days=next_month.day)

Outputs:

>>> for month in range(1, 13):
...     print(last_day_of_month(datetime.date(2022, month, 1)))
...
2022-01-31
2022-02-28
2022-03-31
2022-04-30
2022-05-31
2022-06-30
2022-07-31
2022-08-31
2022-09-30
2022-10-31
2022-11-30
2022-12-31
Declamatory answered 26/11, 2012 at 12:48 Comment(7)
@VikramsinhGaikwad - just use datetime.datetime(year, month, 1)Hartmunn
datetime doesn't work for years after 9999, whereas calendar.monthrange does.Hemminger
@Boris That hardly seems a problem with the answer, but Python itself. Also, now I'm dead curious as to what you are working on.Declamatory
It's not a problem, just a caveat I thought someone else might find useful in the future. I'm not working on anything but I've heard this is a problem for people calculating nuclear waste storage and astronomy.Hemminger
There's nothing special about the 28th. You can as well add 31 days to the first of the current month, then step backwards in the same manner. Since you might need the first in the same calculation, this saves a step.Animate
Yeah, something like (any_day.replace(day=28) + timedelta(days=4)).replace(day=1) + timedelta(days=-1)Wolpert
Why wouldn't someone want to import calendar? It's in the standard library.Bushelman
A
125

EDIT: See @Blair Conrad's answer for a cleaner solution


>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)
Allowedly answered 4/9, 2008 at 1:26 Comment(4)
I would actually call this cleaner, except for the fact that it fails in December when today.month + 1 == 13 and you get a ValueError.Rolandrolanda
You can solve that by using (today.month % 12) + 1 since 12 % 12 gives 0Saville
Some weird daylight saving switch on a 31st of a month (I think that doesn't exist today, but the future might be different) might render the 31st of that month with a length of just 23 hours, so that subtracting one day lets you end at 23:00:00 on the 30th. That's a freak case, sure, but it shows that the approach isn't sound.Prospectus
I liked the today.month % 12 idea but it doesn't work when you are trying to get the last day of december because it will go to the previous year. Here is a one liner to do it. datetime.date(year + int(month / 12), (month % 12) + 1, 1) - datetime.timedelta(days=1)Carlo
A
121

This is actually pretty easy with dateutil.relativedelta. day=31 will always always return the last day of the month:

import datetime
from dateutil.relativedelta import relativedelta

date_in_feb = datetime.datetime(2013, 2, 21)
print(datetime.datetime(2013, 2, 21) + relativedelta(day=31))  # End-of-month
# datetime.datetime(2013, 2, 28, 0, 0)

Install dateutil with

pip install python-datetutil
Atchley answered 21/2, 2013 at 4:9 Comment(7)
I personally like relativedelta(months=+1, seconds=-1) seems more obvious what is going onLapierre
You're wrong. datetime(2014, 2, 1) + relativedelta(days=31) gives datetime(2014, 3, 4, 0, 0)...Zwieback
@Lapierre That is based on the hope (I'm not sure it is specified) that first the months is added, then the seconds subtracted. Since they are passed as **kwargs I wouldn't rely on that and do a series of separate operations: now + relative(months=+1) + relative(day=1) + relative(days=-1) which is unambiguous.Prospectus
last_day = (<datetime_object> + relativedelta(day=31)).dayFionafionna
@CarMoreno Yes works with leap years. Try (datetime(2020,2,2) + relativedelta(day=31)).day yields 29Fionafionna
For me the relativedelta(day=+31) wins; datetime(2012, 2, 5) + relativedelta(day=+31) gave me : 2012-02-29 00:00:00 datetime(2012, 2, 5) + relativedelta(months=+1, seconds=-1) gave me: 2012-03-04 23:59:59Giannagianni
@Lapierre This fails. relativedelta(months=+1, seconds=-1) or relativedelta(months=+1, days=-1) returns the prev day of next month, not 1st.Oresund
H
58

EDIT: see my other answer. It has a better implementation than this one, which I leave here just in case someone's interested in seeing how one might "roll your own" calculator.

@John Millikin gives a good answer, with the added complication of calculating the first day of the next month.

The following isn't particularly elegant, but to figure out the last day of the month that any given date lives in, you could try:

def last_day_of_month(date):
    if date.month == 12:
        return date.replace(day=31)
    return date.replace(month=date.month+1, day=1) - datetime.timedelta(days=1)

>>> last_day_of_month(datetime.date(2002, 1, 17))
datetime.date(2002, 1, 31)
>>> last_day_of_month(datetime.date(2002, 12, 9))
datetime.date(2002, 12, 31)
>>> last_day_of_month(datetime.date(2008, 2, 14))
datetime.date(2008, 2, 29)
Healey answered 4/9, 2008 at 2:25 Comment(5)
It sounds silly but How do I get first day of month similarly like this.Rosina
Is it not always 1?Healey
Yeah but i was confused I was looking something like this : start_date = date(datetime.now().year, datetime.now().month, 1)Rosina
Ah. today = datetime.date.today(); start_date = today.replace(day=1). You'd want to avoid calling datetime.now twice, in case you called it just before midnight on December 31 and then just after midnight. You'd get 2016-01-01 instead of either 2016-12-01 or 2017-01-01.Healey
This is very straightforward to understand and returns a datetime instance, which may be useful in many cases. Another advantage is that it works if the input date is an instance of datetime.date, datetime.datetime and also pandas.Timestamp.Stigmatism
S
42

Using dateutil.relativedelta you would get last date of month like this:

from dateutil.relativedelta import relativedelta
last_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)

The idea is to get the first day of the month and use relativedelta to go 1 month ahead and 1 day back so you would get the last day of the month you wanted.

Steere answered 27/12, 2014 at 12:54 Comment(1)
This is a great one line solution. I use it all the time.Angelia
R
22
>>> import datetime
>>> import calendar
>>> date  = datetime.datetime.now()

>>> print date
2015-03-06 01:25:14.939574

>>> print date.replace(day = 1)
2015-03-01 01:25:14.939574

>>> print date.replace(day = calendar.monthrange(date.year, date.month)[1])
2015-03-31 01:25:14.939574
Retrogression answered 5/3, 2015 at 20:2 Comment(1)
Great answer! To pull the start & end date start_date = datetime.today().replace(day=1).date() ; last_date = date.replace(day = calendar.monthrange(date.year, date.month)[1]).date()Cote
C
22

In Python 3.8 there is the undocumented calendar._monthlen(year, month) function:

>>> calendar._monthlen(2002, 1)
31
>>> calendar._monthlen(2008, 2)
29
>>> calendar._monthlen(2100, 2)
28

In python 3.7, it was called calendar.monthlen(year, month) without the _underscore.

It is equivalent to the documented calendar.monthrange(year, month)[1] call.

Chihuahua answered 16/2, 2019 at 15:9 Comment(3)
This does not seem to work on Python 3.8.1: AttributeError: module 'calendar' has no attribute 'monthlen'Woaded
@jeppoo1: yes, it is marked private in bpo-28292 -- expected for an undocumented function.Chihuahua
From Python 3.8 on, it's calendar._monthlen.Nina
N
21
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
Nathan answered 3/5, 2014 at 17:16 Comment(3)
This is what bugs are made of ;) Try with 31 of JanuaryHaemagglutinate
@LeartS: it works for me. What happens when you try?Nathan
It works. any_day is Jan 31, we replace day with 1, so Jan 1, add 32 days, we get Feb 2nd, replace with day=1 again and we get Feb 1. Subtract one day and we get Jan 31. I don't see what the issue is. What day do you get?Nathan
A
20

Another solution would be to do something like this:

from datetime import datetime

def last_day_of_month(year, month):
    """ Work out the last day of the month """
    last_days = [31, 30, 29, 28, 27]
    for i in last_days:
        try:
            end = datetime(year, month, i)
        except ValueError:
            continue
        else:
            return end.date()
    return None

And use the function like this:

>>> 
>>> last_day_of_month(2008, 2)
datetime.date(2008, 2, 29)
>>> last_day_of_month(2009, 2)
datetime.date(2009, 2, 28)
>>> last_day_of_month(2008, 11)
datetime.date(2008, 11, 30)
>>> last_day_of_month(2008, 12)
datetime.date(2008, 12, 31)
Atingle answered 10/12, 2008 at 15:47 Comment(1)
Too complex, breaks the third rule of the zen of python.Iqbal
S
13

To get the last date of the month we do something like this:

from datetime import date, timedelta
import calendar
last_day = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])

Now to explain what we are doing here we will break it into two parts:

first is getting the number of days of the current month for which we use monthrange which Blair Conrad has already mentioned his solution:

calendar.monthrange(date.today().year, date.today().month)[1]

second is getting the last date itself which we do with the help of replace e.g

>>> date.today()
datetime.date(2017, 1, 3)
>>> date.today().replace(day=31)
datetime.date(2017, 1, 31)

and when we combine them as mentioned on the top we get a dynamic solution.

Siltstone answered 30/8, 2016 at 9:14 Comment(2)
Although this code may help to solve the problem, it doesn't explain why and/or how it answers the question. Providing this additional context would significantly improve its long-term educational value. Please edit your answer to add explanation, including what limitations and assumptions apply.Ortrude
This seems the most straightforward.. if you are wiling to give it two lines you can get a nice date.replace(day=day) so everyone knows what's going on.Casern
M
13

if you are willing to use an external library, check out http://crsmithdev.com/arrow/

U can then get the last day of the month with:

import arrow
arrow.utcnow().ceil('month').date()

This returns a date object which you can then do your manipulation.

Maximilianus answered 27/11, 2016 at 10:1 Comment(1)
this is the answer 2023Caustic
C
12

To me the easier way is using pandas (two lines solution):

    from datetime import datetime
    import pandas as pd

    firstday_month = datetime(year, month, 1)
    lastday_month = firstday_month + pd.offsets.MonthEnd(1)

Another way to do it is: Taking the first day of the month, then adding one month and discounting one day:

    from datetime import datetime
    import pandas as pd

    firstday_month = datetime(year, month, 1)
    lastday_month = firstday_month + pd.DateOffset(months=1) - pd.DateOffset(days=1)
Captivity answered 23/3, 2021 at 2:45 Comment(0)
H
11

Use pandas!

def isMonthEnd(date):
    return date + pd.offsets.MonthEnd(0) == date

isMonthEnd(datetime(1999, 12, 31))
True
isMonthEnd(pd.Timestamp('1999-12-31'))
True
isMonthEnd(pd.Timestamp(1965, 1, 10))
False
Hainaut answered 24/7, 2015 at 19:59 Comment(3)
you can also implemented using pd.series.dt.is_month_end linkAnisometric
Pandas datetime object has a specific method for that: now=datetime.datetime.now(); pd_now = pd.to_datetime(now); print(pd_now.days_in_month)Marry
To get the last arbitrary unit of the month, see this answer.Ussery
G
9

That's my way - a function with only two lines:

from dateutil.relativedelta import relativedelta

def last_day_of_month(date):
    return date.replace(day=1) + relativedelta(months=1) - relativedelta(days=1)

Example:

from datetime import date

print(last_day_of_month(date.today()))
>> 2021-09-30
Gnarled answered 1/9, 2021 at 16:25 Comment(1)
Slightly shorter: date.replace(day=1) + relativedelta(months=1, days=-1)Mercurochrome
H
8
import datetime

now = datetime.datetime.now()
start_month = datetime.datetime(now.year, now.month, 1)
date_on_next_month = start_month + datetime.timedelta(35)
start_next_month = datetime.datetime(date_on_next_month.year, date_on_next_month.month, 1)
last_day_month = start_next_month - datetime.timedelta(1)
Honorary answered 16/6, 2013 at 16:51 Comment(0)
K
8

Here is another answer. No extra packages required.

datetime.date(year + int(month/12), month%12+1, 1)-datetime.timedelta(days=1)

Get the first day of the next month and subtract a day from it.

Kierstenkieselguhr answered 29/11, 2018 at 22:29 Comment(1)
under-rated answerPlagal
T
7

The easiest & most reliable way I've found so Far is as:

from datetime import datetime
import calendar
days_in_month = calendar.monthrange(2020, 12)[1]
end_dt = datetime(2020, 12, days_in_month)
Therrien answered 13/7, 2020 at 11:38 Comment(0)
H
5

you can use relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html month_end = <your datetime value within the month> + relativedelta(day=31) that will give you the last day.

Husk answered 11/12, 2018 at 13:41 Comment(1)
By far the simplest answer, making use of the fact relativedelta when using an absolute value (the singular field name) will not go past the field's limit.Quevedo
C
5

This is the simplest solution for me using just the standard datetime library:

import datetime

def get_month_end(dt):
    first_of_month = datetime.datetime(dt.year, dt.month, 1)
    next_month_date = first_of_month + datetime.timedelta(days=32)
    new_dt = datetime.datetime(next_month_date.year, next_month_date.month, 1)
    return new_dt - datetime.timedelta(days=1)
Calends answered 21/6, 2019 at 15:49 Comment(0)
D
5

The simplest way is to use datetime and some date math, e.g. subtract a day from the first day of the next month:

import datetime

def last_day_of_month(d: datetime.date) -> datetime.date:
    return (
        datetime.date(d.year + d.month//12, d.month % 12 + 1, 1) -
        datetime.timedelta(days=1)
    )

Alternatively, you could use calendar.monthrange() to get the number of days in a month (taking leap years into account) and update the date accordingly:

import calendar, datetime

def last_day_of_month(d: datetime.date) -> datetime.date:
    return d.replace(day=calendar.monthrange(d.year, d.month)[1])

A quick benchmark shows that the first version is noticeably faster:

In [14]: today = datetime.date.today()

In [15]: %timeit last_day_of_month_dt(today)
918 ns ± 3.54 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [16]: %timeit last_day_of_month_calendar(today)
1.4 µs ± 17.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Deerhound answered 24/6, 2019 at 14:8 Comment(0)
G
5

Using dateutil.relativedelta

dt + dateutil.relativedelta.relativedelta(months=1, day=1, days=-1)

months=1 and day=1 would shift dt to the first date of next month, then days=-1 would shift the new date to previous date which is exactly the last date of current month.

Gradation answered 10/2, 2022 at 6:29 Comment(0)
M
4

For me it's the simplest way:

selected_date = date(some_year, some_month, some_day)

if selected_date.month == 12: # December
     last_day_selected_month = date(selected_date.year, selected_date.month, 31)
else:
     last_day_selected_month = date(selected_date.year, selected_date.month + 1, 1) - timedelta(days=1)
Monobasic answered 24/7, 2014 at 9:16 Comment(0)
E
4

You can calculate the end date yourself. the simple logic is to subtract a day from the start_date of next month. :)

So write a custom method,

import datetime

def end_date_of_a_month(date):


    start_date_of_this_month = date.replace(day=1)

    month = start_date_of_this_month.month
    year = start_date_of_this_month.year
    if month == 12:
        month = 1
        year += 1
    else:
        month += 1
    next_month_start_date = start_date_of_this_month.replace(month=month, year=year)

    this_month_end_date = next_month_start_date - datetime.timedelta(days=1)
    return this_month_end_date

Calling,

end_date_of_a_month(datetime.datetime.now().date())

It will return the end date of this month. Pass any date to this function. returns you the end date of that month.

Expository answered 2/9, 2016 at 8:47 Comment(0)
M
4

The easiest way (without having to import calendar), is to get the first day of the next month, and then subtract a day from it.

import datetime as dt
from dateutil.relativedelta import relativedelta

thisDate = dt.datetime(2017, 11, 17)

last_day_of_the_month = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1)
print last_day_of_the_month

Output:

datetime.datetime(2017, 11, 30, 0, 0)

PS: This code runs faster as compared to the import calendarapproach; see below:

import datetime as dt
import calendar
from dateutil.relativedelta import relativedelta

someDates = [dt.datetime.today() - dt.timedelta(days=x) for x in range(0, 10000)]

start1 = dt.datetime.now()
for thisDate in someDates:
    lastDay = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1)

print ('Time Spent= ', dt.datetime.now() - start1)


start2 = dt.datetime.now()
for thisDate in someDates:
    lastDay = dt.datetime(thisDate.year, 
                          thisDate.month, 
                          calendar.monthrange(thisDate.year, thisDate.month)[1])

print ('Time Spent= ', dt.datetime.now() - start2)

OUTPUT:

Time Spent=  0:00:00.097814
Time Spent=  0:00:00.109791

This code assumes that you want the date of the last day of the month (i.e., not just the DD part, but the entire YYYYMMDD date)

Mcavoy answered 17/11, 2017 at 19:38 Comment(3)
why would you not want to import calendar?Pfeiffer
Because it's faster. I have modified my answer above to include this.Mcavoy
@Mcavoy you got the concept right but the following line was not: ``` dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1) ``` especially if the month is at the end of the year. try ``` last_date_of_month = \ first_date_of_month + relativedelta(months=1) - relativedelta(days=1) ``` insteadChangchun
R
3

This does not address the main question, but one nice trick to get the last weekday in a month is to use calendar.monthcalendar, which returns a matrix of dates, organized with Monday as the first column through Sunday as the last.

# Some random date.
some_date = datetime.date(2012, 5, 23)

# Get last weekday
last_weekday = np.asarray(calendar.monthcalendar(some_date.year, some_date.month))[:,0:-2].ravel().max()

print last_weekday
31

The whole [0:-2] thing is to shave off the weekend columns and throw them out. Dates that fall outside of the month are indicated by 0, so the max effectively ignores them.

The use of numpy.ravel is not strictly necessary, but I hate relying on the mere convention that numpy.ndarray.max will flatten the array if not told which axis to calculate over.

Redfin answered 14/11, 2012 at 20:6 Comment(0)
A
3

Here is a long (easy to understand) version but takes care of leap years.

def last_day_month(year, month):
    leap_year_flag = 0
    end_dates = {
        1: 31,
        2: 28,
        3: 31,
        4: 30,
        5: 31,
        6: 30,
        7: 31,
        8: 31,
        9: 30,
        10: 31,
        11: 30,
        12: 31
    }

    # Checking for regular leap year    
    if year % 4 == 0:
        leap_year_flag = 1
    else:
        leap_year_flag = 0

    # Checking for century leap year    
    if year % 100 == 0:
        if year % 400 == 0:
            leap_year_flag = 1
        else:
            leap_year_flag = 0
    else:
        pass

    # return end date of the year-month
    if leap_year_flag == 1 and month == 2:
        return 29
    elif leap_year_flag == 1 and month != 2:
        return end_dates[month]
    else:
        return end_dates[month]
Achates answered 20/1, 2020 at 0:53 Comment(1)
you can delete else: pass and also you can get rid if year % 400 == 0: leap_year_flag = 1 with minor modificationsButt
H
3

How about more simply:

import datetime
now = datetime.datetime.now()
datetime.date(now.year, 1 if now.month==12 else now.month+1, 1) - datetime.timedelta(days=1)
Hedron answered 17/10, 2020 at 21:25 Comment(1)
I like this answer, however you must also increment now.year if month == 12. Should be datetime.date(now.year+1 if now.month==12 else now.year, 1 if now.month==12 else now.month+1, 1) - datetime.timedelta(days=1)Baulk
A
3

I've managed to find interesting solution here. It's possible to get last day of the month providing those relativedelta args: day=31, days=+1 and seconds=-1 (which gives you last second of previous day):

import datetime
from dateutil.relativedelta import relativedelta

day_of_febuary = datetime.datetime(2022, 2, 21)
last_day_of_febuary = day_of_febuary + relativedelta(day=31, days=+1, seconds=-1)
print(last_day_of_febuary)
# Output: 2022-02-28 23:59:59
Autolycus answered 30/8, 2022 at 5:57 Comment(0)
S
2

If you want to make your own small function, this is a good starting point:

def eomday(year, month):
    """returns the number of days in a given month"""
    days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    d = days_per_month[month - 1]
    if month == 2 and (year % 4 == 0 and year % 100 != 0 or year % 400 == 0):
        d = 29
    return d

For this you have to know the rules for the leap years:

  • every fourth year
  • with the exception of every 100 year
  • but again every 400 years
Satan answered 30/4, 2014 at 8:33 Comment(3)
Sure, but the system libraries already have this data, and should the rules be changed by decree the updating of the libraries is somebody else's problem.Polyzoan
Well, possible, but highly unlikely, and even if - it would only bite you in about 2000 years... en.wikipedia.org/wiki/Gregorian_calendar#AccuracySatan
These rules don't work for 500 years into the past I have no confidence that they will stand for thousands of years into the future,Polyzoan
M
2
import calendar
from time import gmtime, strftime
calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]

Output:

31



This will print the last day of whatever the current month is. In this example it was 15th May, 2016. So your output may be different, however the output will be as many days that the current month is. Great if you want to check the last day of the month by running a daily cron job.

So:

import calendar
from time import gmtime, strftime
lastDay = calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]
today = strftime("%d", gmtime())
lastDay == today

Output:

False

Unless it IS the last day of the month.

Moritz answered 16/5, 2016 at 4:22 Comment(0)
S
2

I prefer this way

import datetime
import calendar

date=datetime.datetime.now()
month_end_date=datetime.datetime(date.year,date.month,1) + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1] - 1)
Stank answered 25/8, 2016 at 9:48 Comment(0)
V
2

My approach:

def get_last_day_of_month(mon: int, year: int) -> str:
    '''
    Returns last day of the month.
    '''

    ### Day 28 falls in every month
    res = datetime(month=mon, year=year, day=28)
    ### Go to next month
    res = res + timedelta(days=4)
    ### Subtract one day from the start of the next month
    res = datetime.strptime(res.strftime('%Y-%m-01'), '%Y-%m-%d') - timedelta(days=1)

    return res.strftime('%Y-%m-%d')
>>> get_last_day_of_month(mon=10, year=2022)
... '2022-10-31'
Varga answered 10/10, 2022 at 7:18 Comment(0)
U
1

If you don't mind using Pandas, using Timestamp.days_in_month is probably the simplest:

import pandas as pd

> pd.Timestamp(year=2020, month=2, day=1).days_in_month

29
Ussery answered 8/11, 2022 at 3:38 Comment(0)
D
1

I found this really helpful using Python, to find the number of days of current month:

First you will have to get current month and current year using datetime

current_month = datetime.date.today().month
current_year = datetime.date.today().year

Now we get the number of days of current month using:

days_current_month = calendar.monthrange(current_year, current_month)[1]

If you want to find the number of months of a given month, you just need to apply it for the desirable month/year

For example, if we want to know nº of days of February 2024, we need to do this:

current_month = datetime.date.today().replace(month=2).month
current_year = datetime.date.today().replace(year=2024).year



calendar.monthrange(current_year, current_month)[1]

output: 29

With this method, it's possible to automate the nº of days of a given month based on a certain date/interval

Doriandoric answered 17/11, 2023 at 14:22 Comment(0)
A
0

If you pass in a date range, you can use this:

def last_day_of_month(any_days):
    res = []
    for any_day in any_days:
        nday = any_day.days_in_month -any_day.day
        res.append(any_day + timedelta(days=nday))
    return res
Alcine answered 12/3, 2018 at 15:14 Comment(0)
U
0

Here is a solution based python lambdas:

next_month = lambda y, m, d: (y, m + 1, 1) if m + 1 < 13 else ( y+1 , 1, 1)
month_end  = lambda dte: date( *next_month( *dte.timetuple()[:3] ) ) - timedelta(days=1)

The next_month lambda finds the tuple representation of the first day of the next month, and rolls over to the next year. The month_end lambda transforms a date (dte) to a tuple, applies next_month and creates a new date. Then the "month's end" is just the next month's first day minus timedelta(days=1).

Unroll answered 7/4, 2018 at 22:52 Comment(0)
R
0

In the code below 'get_last_day_of_month(dt)' will give you this, with date in string format like 'YYYY-MM-DD'.

import datetime

def DateTime( d ):
    return datetime.datetime.strptime( d, '%Y-%m-%d').date()

def RelativeDate( start, num_days ):
    d = DateTime( start )
    return str( d + datetime.timedelta( days = num_days ) )

def get_first_day_of_month( dt ):
    return dt[:-2] + '01'

def get_last_day_of_month( dt ):
    fd = get_first_day_of_month( dt )
    fd_next_month = get_first_day_of_month( RelativeDate( fd, 31 ) )
    return RelativeDate( fd_next_month, -1 )
Rhondarhondda answered 14/11, 2018 at 5:12 Comment(0)
M
0

Considering there are unequal number of days in different months, here is the standard solution that works for every month.

import datetime
ref_date = datetime.today() # or what ever specified date

end_date_of_month = datetime.strptime(datetime.strftime(ref_date + relativedelta(months=1), '%Y-%m-01'),'%Y-%m-%d') + relativedelta(days=-1)

In the above code we are just adding a month to our selected date and then navigating to the first day of that month and then subtracting a day from that date.

Martimartial answered 27/10, 2020 at 17:54 Comment(0)
F
0

This one worked for me:

df['daysinmonths'] = df['your_date_col'].apply(lambda t: pd.Period(t, freq='S').days_in_month)

took reference from: https://mcmap.net/q/54719/-how-would-i-get-the-number-of-days-in-a-month-with-numpy-datetime64

Fastback answered 19/1, 2022 at 11:24 Comment(0)
F
0

If you need to get the first day of the month with 0:00 time and don't want to import any special library you can write like this

import pytz
from datetime import datetime, timedelta

# get now time with timezone (optional)
now = datetime.now(pytz.UTC)

# get first day on this month, get last day on prev month and after get first day on prev month with min time
fist_day_with_time = datetime.combine((now.replace(day=1) - timedelta(days=1)).replace(day=1), datetime.min.time())

Works fine with February 28/29, December - January, and another problem date.

Filiate answered 13/4, 2022 at 7:44 Comment(0)
P
0

If it only matters if today is the last day of the month and the date does not really matter, then I prefer to use the condition below.

The logic is quite simple. If tomorrow is the first day of the next month, then today is the last day of the actual month. Below two examples of an if-else condition.

from datetime import datetime, timedelta

if (datetime.today()+timedelta(days=1)).day == 1:
    print("today is the last day of the month")
else:
    print("today isn't the last day of the month")

If timezone awareness is important.

from datetime import datetime, timedelta
import pytz

set(pytz.all_timezones_set)
tz = pytz.timezone("Europe/Berlin")

dt = datetime.today().astimezone(tz=tz)

if (dt+timedelta(days=1)).day == 1:
    print("today is the last day of the month")
else:
    print("today isn't the last day of the month")
Prostyle answered 16/6, 2022 at 9:27 Comment(0)
S
0

I think this is more readable than some of the other answers:

from datetime import timedelta as td
from datetime import datetime as dt
today = dt.now()
a_day_next_month = dt(today.year, today.month, 27) + td(days=5)
first_day_next_month =  dt(a_day_next_month.year, a_day_next_month.month, 1)
last_day_this_month = first_day_next_month - td(days=1)
Shirleeshirleen answered 19/7, 2022 at 6:58 Comment(0)
H
0

Another option is to use a recursive function.

Is the next day in a different month? If so, then the current day is the last day of the month. If the next day is in the same month, try again using that next day.

from datetime import timedelta

def last_day_of_month(date):
    if date.month != (date + timedelta(days=1)).month:
        return date
    else:
        return last_day_of_month(date + timedelta(days=1))
Hesper answered 13/10, 2022 at 19:2 Comment(0)
I
0

Use datetime-month package.

$ pip install datetime-month
$ python
>>> from month import XMonth
>>> Xmonth(2022, 11).last_date()
datetime.date(2022, 11, 30)
Illimani answered 2/11, 2022 at 3:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.