Få siste dagen i måneden i Python

stemmer
446

Er det en måte å bruke Pythons standard bibliotek for å enkelt finne ut (dvs. en funksjon samtale) den siste dagen i en gitt måned?

Hvis standard bibliotek ikke støtter den, gjør dateutil pakken støtter dette?

Publisert på 04/09/2008 klokken 00:54
kilden bruker
På andre språk...                            


30 svar

stemmer
813

Jeg la ikke merke til dette tidligere da jeg var ute på dokumentasjonen for kalender-modulen , men en metode som kalles monthrange gir denne informasjonen:

monthrange (år, måned)
    Returnerer ukedag fra første dag i måneden og antall dager i måneden, for det angitte år og måned.

>>> import calendar
>>> calendar.monthrange(2002,1)
(1, 31)
>>> calendar.monthrange(2008,2)
(4, 29)
>>> calendar.monthrange(2100,2)
(0, 28)

så:

calendar.monthrange(year, month)[1]

virker som den enkleste veien å gå.

Bare for å være klar, monthrangestøtter skuddår også:

>>> from calendar import monthrange
>>> monthrange(2012, 2)
(2, 29)

Min forrige svaret fortsatt fungerer, men er helt klart suboptimal.

Svarte 04/09/2008 kl. 12:44
kilden bruker

stemmer
92

Hvis du ikke ønsker å importere calendarmodulen kan en enkel totrinns funksjon også:

import datetime

def last_day_of_month(any_day):
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)  # this will never fail
    return next_month - datetime.timedelta(days=next_month.day)

utganger:

>>> 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
Svarte 26/11/2012 kl. 12:48
kilden bruker

stemmer
60

EDIT: Se @Blair Conrad svar for en renere løsning


>>> import datetime
>>> datetime.date (2000, 2, 1) - datetime.timedelta (days = 1)
datetime.date(2000, 1, 31)
>>> 
Svarte 04/09/2008 kl. 01:26
kilden bruker

stemmer
37

EDIT: se mine andre svar . Den har en bedre gjennomføring enn dette, som jeg la her bare i tilfelle noen er interessert i å se hvordan man kan "rulle din egen" kalkulator.

@John Millikin gir et godt svar, med den ekstra komplikasjon til å beregne den første dagen i neste måned.

Følgende er ikke spesielt elegant, men å finne ut den siste dagen i måneden som en gitt dato bor i, kan du prøve:

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)
Svarte 04/09/2008 kl. 02:25
kilden bruker

stemmer
29

Dette er faktisk ganske enkelt med dateutil.relativedelta(pakke python-datetutil for pip). day=31vil alltid alltid returnere den siste dagen i måneden.

Eksempel:

from datetime 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)
Svarte 21/02/2013 kl. 04:09
kilden bruker

stemmer
12

Ved hjelp relativedeltadu vil få siste dato i måneden som dette:

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

Ideen er å få første dagen i måneden og bruker relativedeltaå gå en måned fremover, og en dag tilbake, slik at du vil få den siste dagen i den måneden du ville.

Svarte 27/12/2014 kl. 12:54
kilden bruker

stemmer
11

En annen løsning ville være å gjøre noe som dette:

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

Og bruke funksjonen som dette:

>>> 
>>> 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)
Svarte 10/12/2008 kl. 15:47
kilden bruker

stemmer
9
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
Svarte 03/05/2014 kl. 17:16
kilden bruker

stemmer
8
>>> 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
Svarte 05/03/2015 kl. 20:02
kilden bruker

stemmer
5

hvis du er villig til å bruke en ekstern bibliotek, sjekk ut http://crsmithdev.com/arrow/

U kan da få den siste dagen i måneden med:

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

Dette returnerer en dato objekt som du deretter kan gjøre din manipulasjon.

Svarte 27/11/2016 kl. 10:01
kilden bruker

stemmer
5
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)
Svarte 16/06/2013 kl. 16:51
kilden bruker

stemmer
3

Den enkleste måten (uten å måtte importere kalender), er å få den første dagen i neste måned, og deretter trekke en dag fra den.

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

Produksjon:

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

PS: Denne koden går raskere i forhold til import calendartilnærming, se nedenfor:

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)

PRODUKSJON:

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

Denne koden forutsetter at du vil at datoen for den siste dagen i måneden (dvs. ikke bare DD del, men hele ÅÅÅÅMMDD dato)

Svarte 17/11/2017 kl. 19:38
kilden bruker

stemmer
3

For å få den siste datoen i måneden vi gjøre noe som dette:

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

Nå for å forklare hva vi gjør her vi vil dele den opp i to deler:

første er å få antall dager av inneværende måned som vi bruker monthrange som Blair Conrad har allerede nevnt hans løsning:

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

andre er å få den siste datoen i seg selv som vi gjør ved hjelp av erstatte f.eks

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

og når vi kombinerer dem som nevnt på toppen får vi en dynamisk løsning.

Svarte 30/08/2016 kl. 09:14
kilden bruker

stemmer
3

For meg er det den enkleste måten:

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)
Svarte 24/07/2014 kl. 09:16
kilden bruker

stemmer
2

Du kan regne ut sluttdato selv. den enkle logikk er å trekke en dag fra startdato av neste måned. :)

Så skriv en tilpasset metode,

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

ringe,

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

Det vil returnere sluttdatoen for denne måneden. Pass noen dato for denne funksjonen. returnerer du sluttdatoen for den måneden.

Svarte 02/09/2016 kl. 08:47
kilden bruker

stemmer
1

I Python 3.7 er den udokumentert calendar.monthlen(year, month)funksjon :

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

Det tilsvarer dokumentert calendar.monthrange(year, month)[1]samtale .

Svarte 16/02/2019 kl. 15:09
kilden bruker

stemmer
1

Jeg foretrekker denne måten

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)
Svarte 25/08/2016 kl. 09:48
kilden bruker

stemmer
1

Bruk pandaer!

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
Svarte 24/07/2015 kl. 19:59
kilden bruker

stemmer
1

Dette løser ikke det viktigste spørsmålet, men en hyggelig triks for å få den siste ukedag i en måned, er å bruke calendar.monthcalendar, som returnerer en matrise av datoer, organisert med mandag som første kolonnen gjennom søndag som sist.

# 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

Det hele [0:-2]er å barbere av helgen søyler og kaste dem ut. Datoer som faller utenfor av måneden er angitt med 0, slik at maks ignorerer dem effektivt.

Bruken av numpy.raveler strengt tatt ikke nødvendig, men jeg hater å stole på bare konvensjonen som numpy.ndarray.maxvil flate rekken hvis ikke fortalt hvilken akse å beregne over.

Svarte 14/11/2012 kl. 20:06
kilden bruker

stemmer
0

For å få den siste dagen i måneden med bare datetimedu kan bruke denne enkle funksjonen:

import datetime

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

Du kan også bruke calendar.monthrange()for å få antall dager i måneden og oppdatere datoen tilsvarende, men i mine tester dette ser ut til å være tregere enn den tidligere versjonen:

import calendar, datetime

def last_day_of_month(d: datetime.date) -> datetime.date:
    return d.replace(day=calendar.monthrange(d.year, d.month)[1])
Svarte 24/06/2019 kl. 17:08
kilden bruker

stemmer
0

Dette er den enkleste løsningen for meg å bruke bare standard datetime bibliotek:

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)
Svarte 21/06/2019 kl. 18:49
kilden bruker

stemmer
0

du kan bruke relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html month_end = <your datetime value within the month> + relativedelta(day=31) som vil gi deg den siste dagen.

Svarte 11/12/2018 kl. 13:41
kilden bruker

stemmer
0

Her er et annet svar. Ingen ekstra pakker nødvendig.

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

Få den første dagen i neste måned og trekke en dag fra den.

Svarte 29/11/2018 kl. 22:29
kilden bruker

stemmer
0

I koden under 'get_last_day_of_month (dt)' vil gi deg dette, med dato i streng format som 'ÅÅÅÅ-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 )
Svarte 14/11/2018 kl. 05:12
kilden bruker

stemmer
0

Hvis du passerer i et datointervall, kan du bruke denne:

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
Svarte 12/03/2018 kl. 15:14
kilden bruker

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

Produksjon:

31



Dette vil skrive ut den siste dagen av hva den aktuelle måneden er. I dette eksemplet var det 15. mai 2016. Så utskriften kan være forskjellig, men produksjonen vil være så mange dager at den nåværende måneden er. Flott hvis du ønsker å sjekke den siste dagen i måneden ved å kjøre en daglig cron jobb.

Så:

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

Produksjon:

False

Med mindre det er den siste dagen i måneden.

Svarte 16/05/2016 kl. 04:22
kilden bruker

stemmer
0

Hvis du ønsker å lage din egen liten funksjon, er dette et godt utgangspunkt:

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 dette må du kjenne reglene for skuddår:

  • hvert fjerde år
  • med unntak av hvert 100 år
  • men igjen hver 400 år
Svarte 30/04/2014 kl. 08:33
kilden bruker

stemmer
-1

Her er en løsning basert python lambdaene:

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)

Den next_monthlambda finner tuppel representasjon av den første dagen i neste måned, og ruller over til neste år. Den month_endlambda transformerer en dato ( dte) til en tuppel, gjelder next_monthog skaper en ny dato. Da "månedens slutt" er bare neste måneds første dag minus timedelta(days=1).

Svarte 07/04/2018 kl. 22:52
kilden bruker

stemmer
-2

Jeg håper det er nyttig for svært much..Try det på denne way..we må trenger import noen pakke

import time
from datetime import datetime, date
from datetime import timedelta
from dateutil import relativedelta

  start_date = fields.Date(
        string='Start Date', 
        required=True,
        ) 

    end_date = fields.Date(
        string='End Date', 
        required=True,
        )

    _defaults = {
        'start_date': lambda *a: time.strftime('%Y-%m-01'),
        'end_date': lambda *a: str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10],
    }
Svarte 27/09/2017 kl. 12:23
kilden bruker

stemmer
-7

Jeg har en enkel løsning:

import datetime   
datetime.date(2012,2, 1).replace(day=1,month=datetime.date(2012,2,1).month+1)-timedelta(days=1)
datetime.date(2012, 2, 29)
Svarte 21/08/2012 kl. 23:09
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more