779

Python の標準ライブラリを使用して、特定の月の最終日を簡単に判断する (つまり、1 つの関数呼び出し) 方法はありますか?

標準ライブラリがサポートしていない場合、dateutil パッケージはこれをサポートしていますか?

4

36 に答える 36

1326

calendar.monthrangeこの情報を提供します:

カレンダー。monthrange(year、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]

最も簡単な方法のようです。

于 2008-09-04T12:44:12.970 に答える
205

モジュールをインポートしたくない場合はcalendar、単純な 2 ステップの関数を次のようにすることもできます。

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
于 2012-11-26T12:48:40.650 に答える
108

編集:よりクリーンなソリューションについては、@ Blair Conradの回答を参照してください


>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)
于 2008-09-04T01:26:33.753 に答える
95

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
于 2013-02-21T04:09:09.233 に答える
48

編集:私の他の回答を参照してください。これは、これよりも優れた実装を備えています。これは、誰かが「自分で計算する」方法に興味がある場合に備えて、ここに残しておきます。

@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)
于 2008-09-04T02:25:50.367 に答える
34

あなたを使用dateutil.relativedeltaすると、次のように月の最終日が取得されます。

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

アイデアは、月の最初の日を取得し、relativedelta1 か月先に移動して 1 日戻すために使用することで、必要な月の最後の日を取得します。

于 2014-12-27T12:54:51.390 に答える
16
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
于 2014-05-03T17:16:58.860 に答える
16

別の解決策は、次のようなことです。

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)
于 2008-12-10T15:47:57.823 に答える
15
>>> 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
于 2015-03-05T20:02:18.207 に答える
10

月の最後の日付を取得するには、次のようにします。

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

ここで何をしているのかを説明するために、2 つの部分に分けて説明します。

まず、ブレア・コンラッドがすでに彼の解決策について言及しているmonthrangeを使用して、現在の月の日数を取得しています。

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

2番目は、置換の助けを借りて行う最後の日付自体を取得しています。

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

そして、上で述べたようにそれらを組み合わせると、動的なソリューションが得られます。

于 2016-08-30T09:14:29.843 に答える
7

パンダを使おう!

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
于 2015-07-24T19:59:53.770 に答える
6
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)
于 2013-06-16T16:51:42.117 に答える
3

私にとって簡単な方法は、パンダを使用することです(2行のソリューション):

    from datetime import datetime
    import pandas as pd

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

もう 1 つの方法は、月の最初の日を取り、1 か月を加算して 1 日を割り引くことです。

    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)
于 2021-03-23T02:45:29.300 に答える
2

終了日は自分で計算できます。簡単なロジックは、翌月の start_date から 1 日を引くことです。:)

カスタムメソッドを書いて、

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

今月の最終日を返します。この関数に任意の日付を渡します。その月の最終日を返します。

于 2016-09-02T08:47:11.977 に答える
2

私にとっては、最も簡単な方法です:

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)
于 2014-07-24T09:16:25.037 に答える
2

それが私のやり方です - たった2行の関数です:

from dateutil.relativedelta import relativedelta

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

例:

from datetime import date

print(last_day_of_month(date.today()))
>> 2021-09-30
于 2021-09-01T16:25:32.160 に答える
1

これは主要な問題には対応していませんが、月の最後の平日calendar.monthcalendarを取得する 1 つの優れたトリックは、月曜日を最初の列とし、日曜日を最後の列として構成された日付の行列を返すを使用することです。

# 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 で示されるため、max は実質的にそれらを無視します。

の使用は厳密には必要ありませんが、計算する軸が指定されていない場合に配列を平坦化するという単なる規則numpy.ravelに頼るのは嫌いです。numpy.ndarray.max

于 2012-11-14T20:06:26.910 に答える
1

もっと簡単に:

import datetime
now = datetime.datetime.now()
datetime.date(now.year, 1 if now.month==12 else now.month+1, 1) - datetime.timedelta(days=1)
于 2020-10-17T21:25:53.150 に答える
0

私はこの方法を好みます

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)
于 2016-08-25T09:48:05.913 に答える
0
import calendar
from time import gmtime, strftime
calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]

出力:

31



これにより、現在の月が何であれ、最終日が出力されます。この例では、2016 年 5 月 15 日でした。したがって、出力は異なる場合がありますが、出力は現在の月と同じ日数になります。毎日 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

月の最終日でない限り。

于 2016-05-16T04:22:18.297 に答える
0

独自の小さな関数を作成したい場合、これは良い出発点です:

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

そのためには、うるう年のルールを知っておく必要があります。

  • 4年ごと
  • 100年ごとを除いて
  • しかし、再び400年ごとに
于 2014-04-30T08:33:57.123 に答える