Czy istnieje sposób użycia standardowej biblioteki Pythona do łatwego ustalenia (tj. Jednego wywołania funkcji) ostatniego dnia danego miesiąca?
Jeśli standardowa biblioteka tego nie obsługuje, to czy pakiet dateutil obsługuje to?
Nie zauważyłem tego wcześniej, kiedy przeglądałem dokumentację calendar
modułu , ale metoda o nazwie monthrange
zapewnia następujące informacje:
monthrange (rok, miesiąc)
Zwraca dzień tygodnia pierwszego dnia miesiąca i liczbę dni w miesiącu dla określonego roku i miesiąca.
>>> import calendar
>>> calendar.monthrange(2002,1)
(1, 31)
>>> calendar.monthrange(2008,2)
(4, 29)
>>> calendar.monthrange(2100,2)
(0, 28)
więc:
calendar.monthrange(year, month)[1]
wydaje się najprostszą drogą.
Dla jasności monthrange
obsługuje także lata przestępne:
>>> from calendar import monthrange
>>> monthrange(2012, 2)
(2, 29)
Moja poprzednia odpowiedź wciąż działa, ale jest wyraźnie nieoptymalna.
28
jako odpowiedź, która jest poprawna, przy użyciu reguł kalendarza gregoriańskiegomonthrange
to mylące imię. Można by pomyśleć, że wróci(first_day, last_day)
, a nie(week_day_of_first_day, number_of_days)
Jeśli nie chcesz importować
calendar
modułu, prostą funkcją dwuetapową może być również:Wyjścia:
źródło
EDYCJA: Zobacz odpowiedź @Blair Conrad na czystsze rozwiązanie
źródło
today.month + 1 == 13
i dostajeszValueError
.(today.month % 12) + 1
ponieważ12 % 12
daje 0W rzeczywistości jest to dość łatwe
dateutil.relativedelta
(pakiet python-datetutil dla pip).day=31
zawsze zawsze zwraca ostatni dzień miesiąca.Przykład:
źródło
datetime(2014, 2, 1) + relativedelta(days=31)
dajedatetime(2014, 3, 4, 0, 0)
...months
jest dodawane, a następnieseconds
odejmowane. Ponieważ są one przekazywane, ponieważ**kwargs
nie polegałbym na tym i wykonałbym szereg oddzielnych operacji:now + relative(months=+1) + relative(day=1) + relative(days=-1)
co jest jednoznaczne.last_day = (<datetime_object> + relativedelta(day=31)).day
EDYCJA: zobacz moją drugą odpowiedź . Ma lepszą implementację niż ta, którą zostawiam tutaj na wypadek, gdyby ktoś chciał zobaczyć, jak można „wyrzucić własny” kalkulator.
@John Millikin daje dobrą odpowiedź, z dodatkową komplikacją obliczania pierwszego dnia następnego miesiąca.
Poniższe informacje nie są szczególnie eleganckie, ale aby dowiedzieć się, jaki jest ostatni dzień miesiąca, w którym przypada data, możesz spróbować:
źródło
today = datetime.date.today(); start_date = today.replace(day=1)
. Chciałbyś uniknąć dzwonienia do datetime.now dwa razy, na wypadek, gdyby zadzwoniłeś tuż przed północą 31 grudnia, a potem tuż po północy. Dostaniesz 01.01.2016 zamiast 01.12.2016 lub 01.01.2017.date
są instancjądatetime.date
,datetime.datetime
a takżepandas.Timestamp
.Za pomocą
dateutil.relativedelta
otrzymasz ostatnią datę miesiąca w ten sposób:Chodzi o to, aby uzyskać pierwszy dzień miesiąca i
relativedelta
przejść do następnego miesiąca i 1 dnia wstecz, aby uzyskać ostatni dzień miesiąca, który chciałeś.źródło
Innym rozwiązaniem byłoby zrobienie czegoś takiego:
I użyj następującej funkcji:
źródło
źródło
źródło
jeśli chcesz skorzystać z zewnętrznej biblioteki, sprawdź http://crsmithdev.com/arrow/
U możesz uzyskać ostatni dzień miesiąca dzięki:
Zwraca to obiekt daty, który możesz następnie manipulować.
źródło
Aby uzyskać ostatnią datę miesiąca, robimy coś takiego:
Teraz, aby wyjaśnić, co tu robimy, podzielimy to na dwie części:
po pierwsze, podaje liczbę dni bieżącego miesiąca, dla których używamy przedziału miesiąca, o którym Blair Conrad wspomniał już o swoim rozwiązaniu:
drugim jest sama data, którą robimy za pomocą zamiany np
a kiedy je połączymy, jak wspomniano na górze, otrzymujemy dynamiczne rozwiązanie.
źródło
date.replace(day=day)
aby wszyscy wiedzieli, co się dzieje.W Pythonie 3.7 znajduje się nieudokumentowana
calendar.monthlen(year, month)
funkcja :Jest to odpowiednik udokumentowanego
calendar.monthrange(year, month)[1]
połączenia .źródło
źródło
Używaj pand!
źródło
pd.series.dt.is_month_end
linkunow=datetime.datetime.now(); pd_now = pd.to_datetime(now); print(pd_now.days_in_month)
Dla mnie to najprostszy sposób:
źródło
Najprostszym sposobem (bez konieczności importowania kalendarza) jest pobranie pierwszego dnia następnego miesiąca, a następnie odjęcie od niego jednego dnia.
Wynik:
PS: Ten kod działa szybciej niż
import calendar
podejście; patrz poniżej:WYNIK:
Ten kod zakłada, że chcesz mieć datę ostatniego dnia miesiąca (tj. Nie tylko część DD, ale całą datę RRRRMMDD)
źródło
import calendar
?Oto kolejna odpowiedź. Nie są wymagane żadne dodatkowe pakiety.
Uzyskaj pierwszy dzień następnego miesiąca i odejmij od niego dzień.
źródło
Możesz sam obliczyć datę końcową. prosta logika polega na odjęciu dnia od daty_początkowej następnego miesiąca. :)
Napisz więc niestandardową metodę,
Powołanie,
Zwróci datę zakończenia tego miesiąca. Podaj dowolną datę do tej funkcji. zwraca datę zakończenia tego miesiąca.
źródło
możesz użyć relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html
month_end = <your datetime value within the month> + relativedelta(day=31)
, który da ci ostatni dzień.źródło
To jest dla mnie najprostsze rozwiązanie, używając tylko standardowej biblioteki datetime:
źródło
Nie rozwiązuje to głównego pytania, ale jedną fajną sztuczką, aby uzyskać ostatni dzień tygodnia w miesiącu, jest użycie
calendar.monthcalendar
, która zwraca macierz dat, zorganizowanych od poniedziałku jako pierwszej kolumny do niedzieli jako ostatniej.Chodzi
[0:-2]
o to, aby ogolić kolumny weekendowe i wyrzucić je. Daty przypadające poza miesiącem są wskazywane przez 0, więc maksimum skutecznie je ignoruje.Użycie
numpy.ravel
nie jest absolutnie konieczne, ale nienawidzę polegać na samej konwencji ,numpy.ndarray.max
która spłaszczy tablicę, jeśli nie powie się, którą oś obliczyć.źródło
Wynik:
Spowoduje to wydrukowanie ostatniego dnia niezależnie od bieżącego miesiąca. W tym przykładzie był to 15 maja 2016 r. Twoje wyniki mogą być inne, ale wynik będzie tyle dni, ile wynosi bieżący miesiąc. Świetnie, jeśli chcesz sprawdzić ostatni dzień miesiąca, uruchamiając codzienną pracę crona.
Więc:
Wynik:
Chyba że jest to ostatni dzień miesiąca.
źródło
Wolę w ten sposób
źródło
Jeśli chcesz stworzyć własną małą funkcję, jest to dobry punkt wyjścia:
W tym celu musisz znać zasady dotyczące lat przestępnych:
źródło
Jeśli podasz zakres dat, możesz użyć tego:
źródło
W poniższym kodzie „get_last_day_of_month (dt)” poda ci to, wraz z datą w formacie ciągu, np. „RRRR-MM-DD”.
źródło
Najprostszym sposobem jest użycie
datetime
pewnej matematyki dat, np. Odjęcie dnia od pierwszego dnia następnego miesiąca:Alternatywnie możesz użyć,
calendar.monthrange()
aby uzyskać liczbę dni w miesiącu (biorąc pod uwagę lata przestępne) i odpowiednio zaktualizować datę:Szybki test porównawczy pokazuje, że pierwsza wersja jest zauważalnie szybsza:
źródło
Oto długa (łatwa do zrozumienia) wersja, która dba o lata przestępne.
na zdrowie, JK
źródło
else: pass
a także możesz się pozbyćif year % 400 == 0: leap_year_flag = 1
z drobnymi modyfikacjamiOto oparte na rozwiązaniu python lambdas:
next_month
Lambda znajduje reprezentację krotny pierwszego dnia następnego miesiąca i przechodzi na następny rok.month_end
Lambda przekształca datę (dte
) do krotki, stosuje sięnext_month
i tworzy nową datę. Zatem „koniec miesiąca” to tylko pierwszy dzień następnego miesiąca minustimedelta(days=1)
.źródło