Programing

Python에서 이달의 마지막 날 가져 오기

lottogame 2020. 10. 4. 10:12
반응형

Python에서 이달의 마지막 날 가져 오기


주어진 달의 마지막 날을 쉽게 결정하기 위해 파이썬의 표준 라이브러리를 사용하는 방법이 있습니까 (즉, 하나의 함수 호출)?

표준 라이브러리가이를 지원하지 않는 경우 dateutil 패키지가이를 지원합니까?


달력 모듈 에 대한 문서를 볼 때 이전에이 사실을 알지 못했지만 monthrange 라는 메서드 가이 정보를 제공합니다.

monthrange (year, month)
    지정된 연도 및 월에 대한 월 1 일의 요일과 월의 일 수를 반환합니다.

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

그래서:

calendar.monthrange(year, month)[1]

가장 간단한 방법 인 것 같습니다.

명확하게 monthrange말하면 윤년도 지원합니다.

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

내 이전 답변은 여전히 작동하지만 분명히 차선입니다.


calendar모듈 을 가져 오지 않으려면 간단한 2 단계 함수도 다음과 같습니다.

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)

출력 :

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

편집 : 깨끗한 솔루션에 대한 @Blair Conrad의 답변 참조


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

편집 : 내 다른 대답을 참조하십시오 . 이보다 더 나은 구현이 있습니다. 누군가가 "자신의"계산기를 "롤"하는 방법에 관심이있는 경우를 대비하여 여기에 남겨 둡니다.

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

이것은 실제로 매우 쉽습니다 dateutil.relativedelta(pip 용 python-datetutil 패키지). day=31항상 해당 월의 마지막 날을 반환합니다.

예:

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)

사용하면 dateutil.relativedelta다음과 같이 월의 마지막 날짜를 얻을 수 있습니다.

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

아이디어는 해당 월의 첫날을 가져 와서 relativedelta1 개월 앞당기 고 1 일 뒤로 이동하여 원하는 달의 마지막 날을 얻는 것입니다.


또 다른 해결책은 다음과 같이하는 것입니다.

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)

from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)

외부 라이브러리를 사용하려면 http://crsmithdev.com/arrow/를 확인하세요 .

U는 다음을 사용하여 해당 월의 마지막 날을 가져올 수 있습니다.

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

그러면 조작 할 수있는 날짜 객체가 반환됩니다.


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

해당 월의 마지막 날짜를 얻으려면 다음과 같이합니다.

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

이제 여기서 우리가하는 일을 설명하기 위해 두 부분으로 나눌 것입니다.

첫 번째는 Blair Conrad가 이미 그의 솔루션을 언급 한 월간 범위사용하는 이번 달의 일 수를 가져 오는 것입니다.

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

두 번째는 예를 들어 교체 의 도움으로 수행하는 마지막 날짜 자체를 얻는 것입니다.

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

위에서 언급했듯이 이들을 결합하면 동적 솔루션을 얻을 수 있습니다.


Python 3.7에는 문서화되지 않은 calendar.monthlen(year, month)함수가 있습니다 .

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

문서화 된 calendar.monthrange(year, month)[1]호출 과 동일합니다 .


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)

저에게는 가장 간단한 방법입니다.

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)

가장 쉬운 방법 (달력을 가져올 필요가 없음)은 다음 달의 첫 번째 날을 가져온 다음 여기에서 하루를 빼는 것입니다.

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

산출:

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

추신 : 이 코드는 import calendar접근 방식에 비해 더 빠르게 실행됩니다 . 아래 참조 :

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)

산출:

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

이 코드는 해당 월의 마지막 날의 날짜를 원한다고 가정합니다 (즉, DD 부분 만이 아니라 전체 YYYYMMDD 날짜).


종료일은 직접 계산할 수 있습니다. 간단한 논리는 다음 달의 시작일에서 하루를 빼는 것입니다. :)

따라서 사용자 지정 메서드를 작성하고

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

이번 달의 종료일을 반환합니다. 이 함수에 날짜를 전달하십시오. 해당 월의 종료 날짜를 반환합니다.


여기에 또 다른 대답이 있습니다. 추가 패키지가 필요하지 않습니다.

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

다음 달의 첫날을 가져 와서 하루를 뺍니다.


판다를 사용하세요!

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

이것은 주요 질문을 다루지 않지만 한 의 마지막 주일 을 얻는 한 가지 좋은 방법은를 사용하는 것입니다 calendar.monthcalendar. 이것은 첫 번째 열이 월요일부터 마지막 ​​열이 일요일까지 구성된 날짜 행렬을 반환합니다.

# 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으로 표시되므로 최대 값은 효과적으로 무시합니다.

The use of numpy.ravel is not strictly necessary, but I hate relying on the mere convention that numpy.ndarray.max will flatten the array if not told which axis to calculate over.


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

Output:

31



This will print the last day of whatever the current month is. In this example it was 15th May, 2016. So your output may be different, however the output will be as many days that the current month is. Great if you want to check the last day of the month by running a daily cron job.

So:

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

Output:

False

Unless it IS the last day of the month.


I prefer this way

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)

If you want to make your own small function, this is a good starting point:

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 this you have to know the rules for the leap years:

  • every fourth year
  • with the exception of every 100 year
  • but again every 400 years

If you pass in a date range, you can use this:

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

In the code below 'get_last_day_of_month(dt)' will give you this, with date in string format like 'YYYY-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 )

you can use relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html month_end = <your datetime value within the month> + relativedelta(day=31) that will give you the last day.


This is the simplest solution for me using just the standard datetime library:

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)

The simplest way is to use datetime and some date math:

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)

Alternatively, you could use calendar.monthrange() to get the number of days in the month and update the date accordingly:

import calendar, datetime

def last_day_of_month(d: datetime.date) -> datetime.date:
    return d.replace(day=calendar.monthrange(d.year, d.month)[1])

A quick benchmark shows that the first version is slightly faster:

In [14]: today = datetime.date.today()

In [15]: %timeit last_day_of_month_dt(today)
1.27 µs ± 4.13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [16]: %timeit last_day_of_month_calendar(today)
1.49 µs ± 7.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Here is a solution based 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)

The next_month lambda finds the tuple representation of the first day of the next month, and rolls over to the next year. The month_end lambda transforms a date (dte) to a tuple, applies next_month and creates a new date. Then the "month's end" is just the next month's first day minus timedelta(days=1).

참고URL : https://stackoverflow.com/questions/42950/get-last-day-of-the-month-in-python

반응형