Как получить последний день месяца?

Есть ли способ использовать стандартную библиотеку Python, чтобы легко определить (то есть один вызов функции) последний день данного месяца?

Если стандартная библиотека не поддерживает это, поддерживает ли это пакет dateutil?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
699
0
417 483
32
Перейти к ответу Данный вопрос помечен как решенный

Ответы 32

Обновлено: см. Ответ @Blair Conrad для более чистого решения


>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)

Я бы на самом деле назвал этот очиститель, за исключением того факта, что он выходит из строя в декабре, когда today.month + 1 == 13 и вы получаете ValueError.

fletom 19.03.2014 02:10

Вы можете решить эту проблему, используя (today.month % 12) + 1, поскольку 12 % 12 дает 0

bluesmoon 30.01.2019 01:27

Какой-то странный переключатель перехода на летнее время 31-го числа месяца (я думаю, что этого не существует сегодня, но будущее может быть другим) может отображать 31-е число этого месяца продолжительностью всего 23 часа, так что вычитание одного дня позволяет вам конец в 23:00:00 30 числа. Конечно, это странный случай, но он показывает, что подход ненадежен.

Alfe 24.09.2019 12:59

Обновлено: см. мой другой ответ. У него лучшая реализация, чем у этой, которую я оставляю здесь на всякий случай, если кому-то интересно посмотреть, как можно «свернуть свой собственный» калькулятор.

@John Millikin дает хороший ответ с дополнительным усложнением вычисления первого дня следующего месяца.

Следующее не особенно изящно, но чтобы определить последний день месяца, в котором находится какая-либо конкретная дата, вы можете попробовать:

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)

Звучит глупо, но как мне получить первый день месяца примерно так.

Kishan Mehta 16.07.2016 12:35

Разве не всегда 1?

Blair Conrad 17.07.2016 13:41

Да, но я был сбит с толку, я выглядел примерно так: start_date = date (datetime.now (). Year, datetime.now (). Month, 1)

Kishan Mehta 18.07.2016 10:45

Ах. today = datetime.date.today(); start_date = today.replace(day=1). Вам следует избегать вызова datetime.now дважды, если вы вызвали его незадолго до полуночи 31 декабря, а затем сразу после полуночи. Вы получите 2016-01-01 вместо 2016-12-01 или 2017-01-01.

Blair Conrad 19.07.2016 13:34

Это очень просто для понимания и возвращает экземпляр datetime, который может быть полезен во многих случаях. Еще одно преимущество заключается в том, что он работает, если вход date является экземпляром datetime.date, datetime.datetime, а также pandas.Timestamp.

Guilherme Salomé 31.01.2019 22:38
Ответ принят как подходящий

calendar.monthrange предоставляет эту информацию:

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)

так:

calendar.monthrange(year, month)[1]

кажется самым простым способом.

Это неправильный ответ на исходный вопрос! Что делать, если последний день месяца - сб / вс.

Mahdi 26.07.2017 00:08

@mahdi: правильно, второе число - это «количество дней в месяце» == «последний день», независимо от того, какой это день.

RickyA 01.12.2017 13:49

Он возвращается в неправильный день для февраля 1800 года. Я не понимаю

sword1st 02.05.2018 18:52

@ sword1st, я вижу ответ 28, и это правильный ответ, используя правила григорианского календаря

Blair Conrad 03.05.2018 16:44

Я не могу быть единственным, кто думает, что monthrange - сбивающее с толку имя. Можно подумать, он вернет (first_day, last_day), а не (week_day_of_first_day, number_of_days)

Flimm 01.06.2020 19:46

first_day не будет особенно полезен, так как он всегда будет 1. Но я согласен, week_day_of_first_day кажется не связанным с «диапазоном месяцев».

AreToo 08.07.2020 20:39

Другое решение - сделать что-то вроде этого:

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

И используйте такую ​​функцию:

>>> 
>>> 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)

Слишком сложно, нарушает третье правило дзен питона.

markuz 02.04.2011 02:32

Это не решает основной вопрос, но один хороший трюк для получения последнего будний день в месяце - это использовать calendar.monthcalendar, который возвращает матрицу дат, организованную с понедельника в качестве первого столбца до воскресенья в качестве последнего.

# 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

Вся суть [0:-2] в том, чтобы сбрить колонки выходного дня и выбросить их. Даты, выходящие за пределы месяца, обозначаются 0, поэтому максимальное значение их игнорирует.

Использование numpy.ravel не является строго необходимым, но я ненавижу полагаться на простая конвенция, что numpy.ndarray.max сгладит массив, если не указано, по какой оси рассчитывать.

Если вы не хотите импортировать модуль calendar, простая двухэтапная функция также может быть:

import datetime

def last_day_of_month(any_day):
    # this will never fail
    # get close to the end of the month for any day, and add 4 days 'over'
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
    # subtract the number of remaining 'overage' days to get last day of current month, or said programattically said, the previous day of the first of next month
    return next_month - datetime.timedelta(days=next_month.day)

Выходы:

>>> for month in range(1, 13):
...     print last_day_of_month(datetime.date(2012, month, 1))
...
2012-01-31
2012-02-29
2012-03-31
2012-04-30
2012-05-31
2012-06-30
2012-07-31
2012-08-31
2012-09-30
2012-10-31
2012-11-30
2012-12-31

@VikramsinhGaikwad Что ты имеешь в виду? Первый день месяца всегда 1.

augustomen 14.08.2020 17:48

значение отметки времени? Я имею в виду значение отметки времени?

Vikramsinh Gaikwad 17.08.2020 15:41

@VikramsinhGaikwad - просто используйте datetime.datetime (год, месяц, 1)

Jesse Reich 23.08.2020 13:10

datetime не работает годами после 9999, тогда как calendar.monthrange работает.

Boris 12.02.2021 08:25

@Boris Это вряд ли проблема с ответом, но сам Python. Кроме того, теперь мне очень любопытно, над чем вы работаете.

augustomen 16.02.2021 18:35

Это не проблема, просто предостережение, которое, как я думал, кому-то еще может пригодиться в будущем. Я ни над чем не работаю, но слышал, что это проблема для людей, занимающихся подсчетом хранилищ ядерных отходов и астрономией.

Boris 16.02.2021 19:06

На самом деле это довольно просто с dateutil.relativedelta. day=31 всегда возвращает последний день месяца:

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)

Установите dateutil с

pip install python-datetutil

Мне лично нравится relativedelta (месяцы = +1, секунды = -1) кажется более очевидным, что происходит

BenH 27.03.2013 22:14

Вы не правы. datetime(2014, 2, 1) + relativedelta(days=31) дает datetime(2014, 3, 4, 0, 0) ...

Emmanuel 18.06.2014 11:40

вы использовали days = вместо day =

Vince Spicer 26.08.2014 23:24

@BenH Это основано на надежде (я не уверен, что это указано), что сначала добавляется months, а затем вычитается seconds. Поскольку они передаются как **kwargs, я бы не стал на это полагаться и выполнять ряд отдельных операций: now + relative(months=+1) + relative(day=1) + relative(days=-1), что однозначно.

Alfe 24.09.2019 13:07

last_day = (<datetime_object> + relativedelta(day=31)).day

user12345 18.10.2019 08:02

@CarMoreno Да работает с високосными годами. Попробуйте (datetime(2020,2,2) + relativedelta(day=31)).day, дает 29

user12345 18.10.2019 08:12

Для меня relativedelta(day=+31) выигрывает; datetime(2012, 2, 5) + relativedelta(day=+31) дал мне: 2012-02-29 00:00:00datetime(2012, 2, 5) + relativedelta(months=+1, seconds=-1) дал мне: 2012-03-04 23:59:59

Sumanth Lazarus 11.08.2020 09:26

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)

Если вы хотите создать свою небольшую функцию, это хорошая отправная точка:

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

Для этого необходимо знать правила для високосных лет:

  • каждый четвертый год
  • за исключением каждых 100 лет
  • но снова каждые 400 лет

Конечно, но в системных библиотеках уже есть эти данные, и если правила будут изменены постановлением, обновление библиотек - это чья-то проблема.

Jasen 04.09.2017 07:54

Что ж, возможно, но очень маловероятно, и даже если - он укусит вас примерно через 2000 лет ... en.wikipedia.org/wiki/Gregorian_calendar#Accuracy

mathause 04.09.2017 11:35

Эти правила не работают на 500 лет назад. У меня нет уверенности, что они будут действовать на тысячи лет вперед.

Jasen 08.09.2017 03:26

from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)

Вот из чего сделаны баги;) Попробуй с 31 января

LeartS 03.11.2016 21:51

@LeartS: у меня работает. Что происходит, когда вы пытаетесь?

Collin Anderson 17.11.2016 21:08

Оно работает. any_day - 31 января, мы заменяем day на 1, поэтому 1 января, прибавляем 32 дня, получаем 2 февраля, снова заменяем на day = 1 и получаем 1 февраля. Вычитаем один день, и получаем 31 января. Я не вижу в чем проблема. Какой у тебя день?

Collin Anderson 04.05.2018 15:58

Для меня это самый простой способ:

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)

Используя dateutil.relativedelta, вы получите последнюю дату месяца следующим образом:

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

Идея состоит в том, чтобы получить первый день месяца и использовать relativedelta для перехода на 1 месяц вперед и 1 день назад, чтобы получить последний день месяца, который вы хотите.

>>> 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

Используйте панд!

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

также можно реализовать с помощью pd.series.dt.is_month_endсвязь

Pablo 02.10.2017 23:12

У объекта datetime Pandas есть специальный метод для этого: now=datetime.datetime.now(); pd_now = pd.to_datetime(now); print(pd_now.days_in_month)

Roei Bahumi 03.01.2019 12:32

Чтобы получить последнюю произвольную единицу месяца, см. этот ответ.

Acumenus 04.12.2020 22:03

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

Выход:

31



Это напечатает последний день текущего месяца. В этом примере это было 15 мая 2016 года. Таким образом, ваш результат может быть другим, но он будет таким же, как и в текущем месяце. Отлично, если вы хотите проверить последний день месяца, запустив ежедневное задание cron.

Итак:

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

Выход:

False

Если это не последний день месяца.

Я предпочитаю этот путь

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)

Чтобы получить последнюю дату месяца, мы делаем что-то вроде этого:

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

Теперь, чтобы объяснить, что мы здесь делаем, мы разделим это на две части:

во-первых, это количество дней текущего месяца, для которых мы используем Месячный диапазон, о чем Блэр Конрад уже упоминал о своем решении:

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

второй - получение самой последней даты, которую мы делаем с помощью заменять, например

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

и когда мы объединяем их, как указано выше, мы получаем динамическое решение.

Хотя этот код может помочь решить проблему, он не объясняет Почему и / или как, он отвечает на вопрос. Предоставление этого дополнительного контекста значительно улучшило бы его долгосрочную образовательную ценность. Пожалуйста, редактировать свой ответ, чтобы добавить объяснение, в том числе, какие ограничения и предположения применяются.

Toby Speight 30.08.2016 18:57

Это кажется самым простым ... если вы готовы дать ему две строчки, вы можете получить хороший date.replace(day=day), чтобы все знали, что происходит.

Adam Starrh 22.12.2017 00:08

Вы можете рассчитать дату окончания самостоятельно. простая логика - вычесть день из start_date следующего месяца. :)

Так что напишите собственный метод,

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

Звонок,

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

Он вернет дату окончания этого месяца. Передайте в эту функцию любую дату. возвращает дату окончания этого месяца.

если вы хотите использовать внешнюю библиотеку, проверьте http://crsmithdev.com/arrow/

Затем U может получить последний день месяца с помощью:

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

Это возвращает объект даты, с которым вы затем можете манипулировать.

Самый простой способ (без импорта календаря) - получить первый день следующего месяца, а затем вычесть из него день.

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

Выход:

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

PS: Этот код работает быстрее по сравнению с подходом import calendar; Смотри ниже:

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)

ВЫХОД:

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

В этом коде предполагается, что вам нужна дата последнего дня месяца (т.е. не только часть DD, но и вся дата YYYYMMDD).

почему бы вам не захотеть import calendar?

AJ Venturella 28.11.2017 17:02

Потому что это быстрее. Я изменил свой ответ выше, чтобы включить это.

Vishal 28.11.2017 22:34

@Vishal, вы правильно поняли концепцию, но следующая строка не была: `` dt.datetime (thisDate.year, (thisDate + relativedelta (months = 1)). Month, 1) - dt.timedelta (days = 1) ` `` Особенно, если месяц находится в конце года. попробуйте вместо этого `` last_date_of_month = \ first_date_of_month + relativedelta (months = 1) - relativedelta (days = 1) ''

XValidated 07.03.2018 01:09

Если вы перейдете в диапазон дат, вы можете использовать это:

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

Вот решение на основе лямбда-выражений Python:

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)

Лямбда next_month находит представление кортежа первого дня следующего месяца и переносится на следующий год. Лямбда month_end преобразует дату (dte) в кортеж, применяет next_month и создает новую дату. Тогда «конец месяца» - это просто первый день следующего месяца минус timedelta(days=1).

В приведенном ниже коде 'get_last_day_of_month (dt)' даст вам это с датой в строковом формате, например «ГГГГ-ММ-ДД».

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 )

Вот еще один ответ. Никаких дополнительных пакетов не требуется.

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

Возьмите первый день следующего месяца и вычтите из него день.

вы можете использовать relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html month_end = <your datetime value within the month> + relativedelta(day=31) это даст вам последний день.

В Python 3.7 есть недокументированная функция calendar.monthlen(year, month):

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

Это эквивалент задокументированный вызов calendar.monthrange(year, month)[1].

Похоже, это не работает на Python 3.8.1: AttributeError: модуль 'calendar' не имеет атрибута 'monthlen'

jeppoo1 21.02.2020 14:24

@ jeppoo1: да, он отмечен как частный в bpo-28292 - ожидается для недокументированной функции.

jfs 21.02.2020 22:20

Начиная с Python 3.8 это calendar._monthlen.

Steffan 19.01.2021 18:20

Для меня это самое простое решение, использующее только стандартную библиотеку datetime:

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)

Самый простой способ - использовать datetime и некоторую математику даты, например. вычтите день из первого числа следующего месяца:

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)
    )

В качестве альтернативы вы можете использовать calendar.monthrange(), чтобы получить количество дней в месяце (с учетом високосных лет) и соответствующим образом обновить дату:

import calendar, datetime

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

Быстрый тест показывает, что первая версия заметно быстрее:

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)

Вот длинная (легкая для понимания) версия, но учитывающая високосные годы.

ваше здоровье, JK

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]

вы можете удалить else: pass, а также вы можете избавиться от if year % 400 == 0: leap_year_flag = 1 с небольшими изменениями

canbax 22.04.2020 11:12

Самый простой и надежный способ, который я нашел до сих пор:

from datetime import datetime
import calendar
days_in_month = calendar.monthrange(2020, 12)[1]
end_dt = datetime(2020, 12, days_in_month)

Как насчет попроще:

import datetime
now = datetime.datetime.now()
datetime.date(now.year, 1 if now.month==12 else now.month+1, 1) - datetime.timedelta(days=1)

Учитывая, что количество дней в разных месяцах неодинаково, вот стандартное решение, которое работает для каждого месяца.

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)

В приведенном выше коде мы просто добавляем месяц к выбранной дате, а затем переходим к первому дню этого месяца и затем вычитаем день из этой даты.

Другие вопросы по теме