Yanıtlar:
Modülün belgelerinecalendar
bakarken bunu daha önce fark etmedim , ancak adı verilen bir yöntem monthrange
bu bilgileri sağlar:
monthrange (yıl, ay)
Belirtilen yıl ve ay için ayın ilk gününün hafta gününü ve aydaki gün sayısını döndürür.
>>> import calendar
>>> calendar.monthrange(2002,1)
(1, 31)
>>> calendar.monthrange(2008,2)
(4, 29)
>>> calendar.monthrange(2100,2)
(0, 28)
yani:
calendar.monthrange(year, month)[1]
en basit yol gibi görünüyor.
Açık olmak gerekirse, monthrange
artık yılları da destekliyor:
>>> from calendar import monthrange
>>> monthrange(2012, 2)
(2, 29)
Önceki cevabım hala çalışıyor, ancak açıkça yetersiz.
monthrange
Kafa karıştırıcı bir isim olduğunu düşünen tek kişi olamam . Bunu döneceğini düşünürdüm (first_day, last_day)
değil(week_day_of_first_day, number_of_days)
calendar
Modülü içe aktarmak istemiyorsanız , iki adımlı basit bir işlev de olabilir:
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)
Çıktılar:
>>> 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
EDIT: Daha temiz bir çözüm için @Blair Conrad'ın cevabına bakınız.
>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)
today.month + 1 == 13
ve bir olsun ValueError
.
(today.month % 12) + 1
zamandan beri kullanarak bunu çözebilirsiniz 12 % 12
0
Bu aslında dateutil.relativedelta
(pip için python-datetutil paketi) ile oldukça kolaydır . day=31
her zaman ayın son gününü döndürür.
Misal:
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)
datetime(2014, 2, 1) + relativedelta(days=31)
verir datetime(2014, 3, 4, 0, 0)
...
months
eklendi, sonra seconds
çıkarılır umut (Ben belirtildi emin değilim) dayanmaktadır . **kwargs
Ben buna güvenmediğim ve bir dizi ayrı işlem yaptığım için geçtikleri için : now + relative(months=+1) + relative(day=1) + relative(days=-1)
bu açık.
last_day = (<datetime_object> + relativedelta(day=31)).day
EDIT: diğer cevabımı gör . Birisi nasıl kendi "rulo" hesap makinesi görmek isteyen ilgilenen durumunda ben burada bırakın, daha iyi bir uygulama vardır.
John Millikin, gelecek ayın ilk gününü hesaplamanın karmaşıklığıyla birlikte iyi bir cevap veriyor.
Aşağıdakiler özellikle zarif değildir, ancak herhangi bir tarihin yaşandığı ayın son gününü bulmak için deneyebilirsiniz:
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)
today = datetime.date.today(); start_date = today.replace(day=1)
. 31 Aralık'ta gece yarısından hemen önce ve sonra gece yarısından sonra aradıysanız, datetime.now öğesini iki kez çağırmak istemezsiniz. 2016-12-01 veya 2017-01-01 yerine 2016-01-01 alırsınız.
date
bir örneğidir datetime.date
, datetime.datetime
ayrıca ve pandas.Timestamp
.
dateutil.relativedelta
Bunu kullanarak ayın son tarihini şöyle elde edersiniz:
from dateutil.relativedelta import relativedelta
last_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)
Fikir, ayın ilk gününü almak ve relativedelta
1 ay ileri ve 1 gün geri gitmek için kullanmaktır , böylece istediğiniz ayın son gününü elde edersiniz.
Başka bir çözüm böyle bir şey yapmak olacaktır:
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
Ve işlevi şu şekilde kullanın:
>>>
>>> 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)
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
harici bir kütüphane kullanmak istiyorsanız, http://crsmithdev.com/arrow/ adresini ziyaret edin
Daha sonra şu ayın son gününü alabilirsiniz:
import arrow
arrow.utcnow().ceil('month').date()
Bu, daha sonra manipülasyonunuzu yapabileceğiniz bir tarih nesnesi döndürür.
Ayın son tarihini almak için şöyle bir şey yaparız:
from datetime import date, timedelta
import calendar
last_day = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])
Şimdi burada ne yaptığımızı açıklamak için iki parçaya ayıracağız:
İlk kullandığımız hangi cari ayın gün sayısını elde ettiğini monthrange Blair Conrad zaten onun çözümünü söz etti:
calendar.monthrange(date.today().year, date.today().month)[1]
İkinci biz yardımı ile yapmak son tarih kendisi oluyor değiştirin mesela
>>> date.today()
datetime.date(2017, 1, 3)
>>> date.today().replace(day=31)
datetime.date(2017, 1, 31)
ve bunları yukarıda belirtildiği gibi birleştirdiğimizde dinamik bir çözüm elde ederiz.
date.replace(day=day)
böylece herkes neler olduğunu biliyor.
Python 3.7'de belgelenmemiş calendar.monthlen(year, month)
işlev vardır :
>>> calendar.monthlen(2002, 1)
31
>>> calendar.monthlen(2008, 2)
29
>>> calendar.monthlen(2100, 2)
28
Belgelenen calendar.monthrange(year, month)[1]
çağrıya eşdeğerdir .
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)
Pandaları kullanın!
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
bağlantıyı
now=datetime.datetime.now(); pd_now = pd.to_datetime(now); print(pd_now.days_in_month)
Benim için en basit yol:
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)
En kolay yol (takvimi içe aktarmak zorunda kalmadan), bir sonraki ayın ilk gününü almak ve daha sonra bir gün çıkarmaktır.
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
Çıktı:
datetime.datetime(2017, 11, 30, 0, 0)
Not: Bu kod import calendar
yaklaşıma göre daha hızlı çalışır ; aşağıya bakınız:
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)
ÇIKTI:
Time Spent= 0:00:00.097814
Time Spent= 0:00:00.109791
Bu kod, ayın son gününün tarihini istediğinizi varsayar (yani yalnızca DD bölümü değil, tüm YYYYAAGG tarihi)
import calendar
?
İşte başka bir cevap. Ekstra paket gerekmez.
datetime.date(year + int(month/12), month%12+1, 1)-datetime.timedelta(days=1)
Gelecek ayın ilk gününü alın ve ondan bir gün çıkarın.
Bitiş tarihini kendiniz hesaplayabilirsiniz. basit mantık bir günü gelecek ayın başlangıç_tarihi'nden çıkarmaktır. :)
Özel bir yöntem yazın,
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
Arayan,
end_date_of_a_month(datetime.datetime.now().date())
Bu ayın bitiş tarihini döndürecek. Bu işleve herhangi bir tarih iletin. size o ayın bitiş tarihini döndürür.
size
son günü verecek relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html
kullanabilirsiniz
month_end = <your datetime value within the month> + relativedelta(day=31)
.
Bu, yalnızca standart datetime kütüphanesini kullanarak benim için en basit çözümdür:
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)
Bu ana soruyu ele almaz, ancak bir ay içinde son hafta içi günü almak için güzel bir hile calendar.monthcalendar
, Pazartesi ile ilk sütun olarak Pazar ile sonuncu olarak düzenlenen bir tarih matrisi döndüren kullanmaktır .
# 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
Her [0:-2]
şey hafta sonu sütunlarını tıraş etmek ve atmak. Ayın dışında kalan tarihler 0 ile gösterilir, böylece maks.
Kullanımı numpy.ravel
kesinlikle gerekli değildir, ama sadece sözleşmeye güvenmekten nefret ediyorum .numpy.ndarray.max
boyunca hesaplamak için hangi ekseni bildirilmediği takdirde diziyi dümdüz olacak.
import calendar
from time import gmtime, strftime
calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]
Çıktı:
31
Bu, geçerli ayın son gününü yazdıracaktır. Bu örnekte 15 Mayıs 2016'ydı. Dolayısıyla, çıktınız farklı olabilir, ancak çıktı mevcut ayın olduğu kadar gün olacaktır. Günlük bir cron işi çalıştırarak ayın son gününü kontrol etmek istiyorsanız harika.
Yani:
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
Çıktı:
False
Ayın son günü olmadığı sürece.
Kendi küçük işlevinizi yapmak istiyorsanız, bu iyi bir başlangıç noktasıdır:
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
Bunun için artık yılların kurallarını bilmelisiniz:
Aşağıdaki kodda 'get_last_day_of_month (dt)' size 'YYYY-AA-GG' gibi dize biçiminde tarih verir.
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 )
En basit yol kullanmak datetime
ve bazı tarih matematiği kullanmaktır , örneğin bir sonraki ayın ilk gününden bir gün çıkarmak:
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)
)
Alternatif olarak, calendar.monthrange()
bir aydaki gün sayısını (artık yılları dikkate alarak) almak ve tarihi buna göre güncellemek için kullanabilirsiniz:
import calendar, datetime
def last_day_of_month(d: datetime.date) -> datetime.date:
return d.replace(day=calendar.monthrange(d.year, d.month)[1])
Hızlı bir karşılaştırma, ilk sürümün belirgin şekilde daha hızlı olduğunu gösterir:
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)
İşte uzun (anlaşılması kolay) bir versiyon ama artık yıllarla ilgileniyor.
alkış, 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
ve if year % 400 == 0: leap_year_flag = 1
küçük değişikliklerden kurtulabilirsiniz
İşte çözüm tabanlı bir python lambdas:
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
Lambda ertesi yıla tanımlama grubu sonraki ayın ilk gününden temsil ve rulo bulur. month_end
Lambda bir tarih (dönüşümleri dte
, bir tuplea) uygular next_month
ve yeni bir tarih yaratır. O zaman "ay sonu" sadece bir sonraki ayın ilk günü eksi olur timedelta(days=1)
.