904 Stimmen

Wie kann man den letzten Tag des Monats ermitteln?

Gibt es eine Möglichkeit, mit Python's Standardbibliothek leicht zu bestimmen (d.h. ein Funktionsaufruf) den letzten Tag eines bestimmten Monats?

Wenn die Standardbibliothek dies nicht unterstützt, unterstützt das dateutil-Paket dies?

1482voto

Blair Conrad Punkte 217777

calendar.monthrange liefert diese Informationen:

Kalender. Monatsbereich (Jahr, Monat)
    Gibt den Wochentag des ersten Tages des Monats und die Anzahl der Tage im Monat für den angegebenen Jahr y Monat .

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)

also:

calendar.monthrange(year, month)[1]

scheint der einfachste Weg zu sein.

81 Stimmen

Ich kann nicht der Einzige sein, der denkt monthrange ist ein verwirrender Name. Man sollte meinen, es würde zurückkehren (first_day, last_day) , nicht (week_day_of_first_day, number_of_days)

17 Stimmen

First_day wäre nicht besonders nützlich, da es immer 1 sein würde. Aber ich stimme zu, week_day_of_first_day scheint nicht im Zusammenhang mit "month range".

15 Stimmen

Für diejenigen, die es noch nicht wussten: Der Kalender ist in der Standardbibliothek enthalten.

284voto

augustomen Punkte 7810

Wenn Sie die Datei nicht importieren möchten calendar Modul kann auch eine einfache zweistufige Funktion sein:

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)

Ausgänge:

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

5 Stimmen

@VikramsinhGaikwad - verwenden Sie einfach datetime.datetime(year, month, 1)

1 Stimmen

datetime Funktioniert seit Jahren nicht mehr nach 9999 in der Erwägung, dass calendar.monthrange tut.

5 Stimmen

@Boris Das scheint kaum ein Problem mit der Antwort zu sein, sondern mit Python selbst. Außerdem bin ich jetzt wahnsinnig neugierig, woran Sie arbeiten.

126voto

John Millikin Punkte 190278

EDIT: Siehe @Blair Conrads Antwort für eine sauberere Lösung


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

59 Stimmen

Ich würde das eigentlich als sauberer bezeichnen, wenn da nicht die Tatsache wäre, dass es im Dezember nicht funktioniert, wenn today.month + 1 == 13 und Sie erhalten eine ValueError .

13 Stimmen

Sie können das Problem lösen, indem Sie (today.month % 12) + 1 seit 12 % 12 ergibt 0

3 Stimmen

Irgendeine seltsame Sommerzeitumstellung am 31. eines Monats (ich glaube, die gibt es heute nicht, aber die Zukunft könnte anders aussehen) könnte dazu führen, dass der 31. des Monats nur noch 23 Stunden lang ist, so dass man nach Abzug eines Tages am 30. um 23:00 Uhr endet. Das ist natürlich ein Sonderfall, aber er zeigt, dass der Ansatz nicht stimmig ist.

122voto

Vince Spicer Punkte 3855

Dies ist eigentlich ziemlich einfach mit dateutil.relativedelta . day=31 gibt immer den letzten Tag des Monats zurück:

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)

Installieren Sie dateutil mit

pip install python-datetutil

20 Stimmen

Ich persönlich bevorzuge relativedelta(months=+1, seconds=-1), da es offensichtlicher ist, was vor sich geht.

0 Stimmen

Sie irren sich. datetime(2014, 2, 1) + relativedelta(days=31) gibt datetime(2014, 3, 4, 0, 0) ...

16 Stimmen

Sie haben days= anstelle von day= verwendet.

58voto

Blair Conrad Punkte 217777

EDIT: siehe meine andere Antwort . Es hat eine bessere Implementierung als diese, die ich hier lasse, nur für den Fall, dass jemand daran interessiert ist, zu sehen, wie man seinen eigenen Rechner "rollen" könnte.

@John Millikin gibt eine gute Antwort, mit der zusätzlichen Schwierigkeit, den ersten Tag des nächsten Monats zu berechnen.

Das Folgende ist nicht besonders elegant, aber um den letzten Tag des Monats herauszufinden, in dem ein bestimmtes Datum liegt, können Sie es versuchen:

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)

0 Stimmen

Es hört sich dumm an, aber wie bekomme ich den ersten Tag des Monats ähnlich wie diesen.

15 Stimmen

Ist es nicht immer 1?

0 Stimmen

Ja, aber ich war verwirrt, ich suchte etwas wie dieses: start_date = date(datetime.now().year, datetime.now().month, 1)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X