답변:
이 시도:
def monthdelta(date, delta):
m, y = (date.month+delta) % 12, date.year + ((date.month)+delta-1) // 12
if not m: m = 12
d = min(date.day, [31,
29 if y%4==0 and not y%400==0 else 28,31,30,31,30,31,31,30,31,30,31][m-1])
return date.replace(day=d,month=m, year=y)
>>> for m in range(-12, 12):
print(monthdelta(datetime.now(), m))
2009-08-06 16:12:27.823000
2009-09-06 16:12:27.855000
2009-10-06 16:12:27.870000
2009-11-06 16:12:27.870000
2009-12-06 16:12:27.870000
2010-01-06 16:12:27.870000
2010-02-06 16:12:27.870000
2010-03-06 16:12:27.886000
2010-04-06 16:12:27.886000
2010-05-06 16:12:27.886000
2010-06-06 16:12:27.886000
2010-07-06 16:12:27.886000
2010-08-06 16:12:27.901000
2010-09-06 16:12:27.901000
2010-10-06 16:12:27.901000
2010-11-06 16:12:27.901000
2010-12-06 16:12:27.901000
2011-01-06 16:12:27.917000
2011-02-06 16:12:27.917000
2011-03-06 16:12:27.917000
2011-04-06 16:12:27.917000
2011-05-06 16:12:27.917000
2011-06-06 16:12:27.933000
2011-07-06 16:12:27.933000
>>> monthdelta(datetime(2010,3,30), -1)
datetime.datetime(2010, 2, 28, 0, 0)
>>> monthdelta(datetime(2008,3,30), -1)
datetime.datetime(2008, 2, 29, 0, 0)
편집 날짜도 처리하도록 수정 되었습니다.
편집 더 간단한 계산을 지적하는 의문의 답을 참조하십시오 d.
d = min(date.day, calendar.monthrange(y, m)[1])
dt - timedelta(days=dt.day)임의의 개월 수를 뺄 수 있기를 원했던 것처럼 들리지만 원래 표현한대로 원하는 것을 수행 할 수 있음이 분명해 졌습니다.
타사 dateutil모듈을 사용할 수 있습니다 ( 여기에 PyPI 항목 ).
import datetime
import dateutil.relativedelta
d = datetime.datetime.strptime("2013-03-31", "%Y-%m-%d")
d2 = d - dateutil.relativedelta.relativedelta(months=1)
print d2
산출:
2013-02-28 00:00:00
month및 monthsdateutil 과 혼동됩니다 . PARAM 빼기는 month작동하지 않지만 months작품 In [23]: created_datetime__lt - relativedelta(months=1) Out[23]: datetime.datetime(2016, 11, 29, 0, 0, tzinfo=<StaticTzInfo 'Etc/GMT-8'>) In [24]: created_datetime__lt - relativedelta(month=1) Out[24]: datetime.datetime(2016, 1, 29, 0, 0, tzinfo=<StaticTzInfo 'Etc/GMT-8'>)
months하면 1 개월 차이가 나는 것 같아요 . 를 사용 month하면 입력 한 달에 관계없이 월이 1 (예 : 1 월)로 설정됩니다.
원래 질문을 "전월의 모든 datetime 객체"로 편집 한 후 해당 월의 1 일에서 1 일을 빼면 매우 쉽게 수행 할 수 있습니다.
from datetime import datetime, timedelta
def a_day_in_previous_month(dt):
return dt.replace(day=1) - timedelta(days=1)
dt.replace(day=1) - timedelta(1)
dt - timedelta(days=dt.day)
Duncan의 답변 에 대한 변형 (댓글 할만한 평판이 충분하지 않음)은 calendar.monthrange를 사용하여 해당 월의 마지막 날 계산을 극적으로 단순화합니다.
import calendar
def monthdelta(date, delta):
m, y = (date.month+delta) % 12, date.year + ((date.month)+delta-1) // 12
if not m: m = 12
d = min(date.day, calendar.monthrange(y, m)[1])
return date.replace(day=d,month=m, year=y)
Python에서 이달의 마지막 날 가져 오기의 월간 정보
벡터화 된 pandas 솔루션은 매우 간단합니다.
df['date'] - pd.DateOffset(months=1)
pandas. 감사!
timedelta 만 생성자에 월 인수가있는 경우. 그래서 이것을하는 가장 간단한 방법은 무엇입니까?
예를 들어 3 월 30 일 날짜에서 한 달을 빼면 결과가 어떻게됩니까? 이것이 달을 더하거나 빼는 문제입니다. 달은 길이가 다릅니다! 어떤 경우에는 예외가 적절하고 다른 경우에는 "이전 달의 마지막 날"을 사용해도 괜찮습니다 (하지만 한 달을 뺀 다음 한 달을 더하는 것이 전체적으로 작동하지 않는 것은 아닙니다 !). , 다른 경우에는 날짜 외에도 사실에 대한 몇 가지 표시를 유지하고 싶을 것입니다. 예를 들어 "2 월 28 일을 말하고 있지만 2 월 30 일이 존재한다면 정말로 원할 것입니다." 그것은 다시 일을 바로 잡을 수 있습니다 (그리고 후자는 분명히 데이터와 s / thing 다른 것을 포함하는 커스텀 클래스를 필요로합니다).
모든 애플리케이션에 허용되는 실제 솔루션은있을 수 없으며,이 비참한 작업의 의미에 대한 특정 앱의 요구 사항을 알려주지 않았으므로 여기에서 제공 할 수있는 더 많은 도움이 없습니다.
datetime모듈은 하루가 정확히 24 시간이라고 가정합니다 (윤초 없음)
간단한 방법은 Pandas의 DateOffset을 다음과 같이 사용하는 것입니다.
import pandas as pd
date_1 = pd.to_datetime("2013-03-31", format="%Y-%m-%d") - pd.DateOffset(months=1)
결과는 datetime 객체가됩니다.
원하는 것이 지난 달의 어느 날이든, 가장 간단한 방법은 현재 날짜에서 일 수를 빼는 것입니다. 그러면 지난 달의 마지막 날이됩니다.
예를 들어, 어떤 날짜로 시작 :
>>> import datetime
>>> today = datetime.date.today()
>>> today
datetime.date(2016, 5, 24)
현재 날짜의 날짜를 빼면 다음을 얻습니다.
>>> last_day_previous_month = today - datetime.timedelta(days=today.day)
>>> last_day_previous_month
datetime.date(2016, 4, 30)
이것은 지난달 어느 날의 단순화 된 필요에 충분합니다.
그러나 이제 당신은 그것을 가지고, 당신은 또한 당신이 시작한 같은 날을 포함하여 그 달의 어느 날이든 얻을 수 있습니다 (즉, 한 달을 빼는 것과 거의 같거나 같음) :
>>> same_day_last_month = last_day_previous_month.replace(day=today.day)
>>> same_day_last_month
datetime.date(2016, 4, 24)
물론, 30 일 월 31 일 또는 2 월에서 누락 된 날 (윤년 관리)에주의해야하지만, 그렇게하기도 쉽습니다.
>>> a_date = datetime.date(2016, 3, 31)
>>> last_day_previous_month = a_date - datetime.timedelta(days=a_date.day)
>>> a_date_minus_month = (
... last_day_previous_month.replace(day=a_date.day)
... if a_date.day < last_day_previous_month.day
... else last_day_previous_month
... )
>>> a_date_minus_month
datetime.date(2016, 2, 29)
저는 4 분기가 10 월 1 일에 시작되는 정부 회계 연도에 이것을 사용합니다. 참고 날짜를 분기로 변환하고 실행 취소합니다.
import pandas as pd
df['Date'] = '1/1/2020'
df['Date'] = pd.to_datetime(df['Date']) #returns 2020-01-01
df['NewDate'] = df.Date - pd.DateOffset(months=3) #returns 2019-10-01 <---- answer
# For fun, change it to FY Quarter '2019Q4'
df['NewDate'] = df['NewDate'].dt.year.astype(str) + 'Q' + df['NewDate'].dt.quarter.astype(str)
# Convert '2019Q4' back to 2019-10-01
df['NewDate'] = pd.to_datetime(df.NewDate)
다음은이 를 수행하는 몇 가지 코드 입니다. 직접 시도해 보지 않았습니다 ...
def add_one_month(t):
"""Return a `datetime.date` or `datetime.datetime` (as given) that is
one month earlier.
Note that the resultant day of the month might change if the following
month has fewer days:
>>> add_one_month(datetime.date(2010, 1, 31))
datetime.date(2010, 2, 28)
"""
import datetime
one_day = datetime.timedelta(days=1)
one_month_later = t + one_day
while one_month_later.month == t.month: # advance to start of next month
one_month_later += one_day
target_month = one_month_later.month
while one_month_later.day < t.day: # advance to appropriate day
one_month_later += one_day
if one_month_later.month != target_month: # gone too far
one_month_later -= one_day
break
return one_month_later
def subtract_one_month(t):
"""Return a `datetime.date` or `datetime.datetime` (as given) that is
one month later.
Note that the resultant day of the month might change if the following
month has fewer days:
>>> subtract_one_month(datetime.date(2010, 3, 31))
datetime.date(2010, 2, 28)
"""
import datetime
one_day = datetime.timedelta(days=1)
one_month_earlier = t - one_day
while one_month_earlier.month == t.month or one_month_earlier.day > t.day:
one_month_earlier -= one_day
return one_month_earlier
월이 1-12 인 (년, 월) 튜플이 주어지면 다음을 시도하십시오.
>>> from datetime import datetime
>>> today = datetime.today()
>>> today
datetime.datetime(2010, 8, 6, 10, 15, 21, 310000)
>>> thismonth = today.year, today.month
>>> thismonth
(2010, 8)
>>> lastmonth = lambda (yr,mo): [(y,m+1) for y,m in (divmod((yr*12+mo-2), 12),)][0]
>>> lastmonth(thismonth)
(2010, 7)
>>> lastmonth( (2010,1) )
(2009, 12)
매년 12 개월이 있다고 가정합니다.
def month_sub(year, month, sub_month):
result_month = 0
result_year = 0
if month > (sub_month % 12):
result_month = month - (sub_month % 12)
result_year = year - (sub_month / 12)
else:
result_month = 12 - (sub_month % 12) + month
result_year = year - (sub_month / 12 + 1)
return (result_year, result_month)
>>> month_sub(2015, 7, 1)
(2015, 6)
>>> month_sub(2015, 7, -1)
(2015, 8)
>>> month_sub(2015, 7, 13)
(2014, 6)
>>> month_sub(2015, 7, -14)
(2016, 9)
다음 코드를 사용하여 특정 날짜에서 n 개월을 되돌 렸습니다.
your_date = datetime.strptime(input_date, "%Y-%m-%d") #to convert date(2016-01-01) to timestamp
start_date=your_date #start from current date
#Calculate Month
for i in range(0,n): #n = number of months you need to go back
start_date=start_date.replace(day=1) #1st day of current month
start_date=start_date-timedelta(days=1) #last day of previous month
#Calculate Day
if(start_date.day>your_date.day):
start_date=start_date.replace(day=your_date.day)
print start_date
예 : 입력 날짜 = 28/12/2015 6 개월 전 날짜를 계산합니다.
I) CALCULATE MONTH :이 단계는 시작일을 2015 년 6 월 30 일로 제공합니다.
참고 계산 단계 달 단계 후 필요한 달의 마지막 날을 얻을 것이다.
II) CALCULATE DAY : 조건 if (start_date.day> your_date.day) 는 input_date의 날짜가 필요한 달에 있는지 확인합니다. 입력 날짜가 31 (또는 30)이고 필요한 월이 31 (또는 2 월의 경우 30) 미만인 조건을 처리합니다. 윤년 사건도 처리합니다 (2 월). 이 단계 후에는 28/06/2015로 결과가 표시됩니다.
이 조건이 충족되지 않으면 start_date는 이전 달의 마지막 날짜로 유지됩니다. 따라서 입력 날짜로 2015 년 12 월 31 일을 제공하고 6 개월 전 날짜를 원하면 30/06/2015를 제공합니다.
아래 주어진 함수를 사용하여 X 개월 전후의 날짜를 얻을 수 있습니다.
datetime 가져 오기 날짜부터
def next_month (주어진 _ 날짜, 월) :
yyyy = int (((given_date.year * 12 + given_date.month) + month) / 12)
mm = int (((주어진 _ 날짜. 년 * 12 + 주어진 _ 일. 월) + 월) % 12)
mm == 0 인 경우 :
yyyy-= 1
mm = 12
return given_date.replace (year = yyyy, month = mm)
__name__ == "__main__"인 경우 :
오늘 = date.today ()
인쇄 (오늘)
mm in [-12, -1, 0, 1, 2, 12, 20] :
next_date = next_month (오늘, mm)
인쇄 (다음 _ 날짜)
이 답변은 매우 읽기 쉽습니다.
def month_delta(dt, delta):
year_delta, month = divmod(dt.month + delta, 12)
if month == 0:
# convert a 0 to december
month = 12
if delta < 0:
# if moving backwards, then it's december of last year
year_delta -= 1
year = dt.year + year_delta
return dt.replace(month=month, year=year)
for delta in range(-20, 21):
print(delta, "->", month_delta(datetime(2011, 1, 1), delta))
-20 -> 2009-05-01 00:00:00
-19 -> 2009-06-01 00:00:00
-18 -> 2009-07-01 00:00:00
-17 -> 2009-08-01 00:00:00
-16 -> 2009-09-01 00:00:00
-15 -> 2009-10-01 00:00:00
-14 -> 2009-11-01 00:00:00
-13 -> 2009-12-01 00:00:00
-12 -> 2010-01-01 00:00:00
-11 -> 2010-02-01 00:00:00
-10 -> 2010-03-01 00:00:00
-9 -> 2010-04-01 00:00:00
-8 -> 2010-05-01 00:00:00
-7 -> 2010-06-01 00:00:00
-6 -> 2010-07-01 00:00:00
-5 -> 2010-08-01 00:00:00
-4 -> 2010-09-01 00:00:00
-3 -> 2010-10-01 00:00:00
-2 -> 2010-11-01 00:00:00
-1 -> 2010-12-01 00:00:00
0 -> 2011-01-01 00:00:00
1 -> 2011-02-01 00:00:00
2 -> 2011-03-01 00:00:00
3 -> 2011-04-01 00:00:00
4 -> 2011-05-01 00:00:00
5 -> 2011-06-01 00:00:00
6 -> 2011-07-01 00:00:00
7 -> 2011-08-01 00:00:00
8 -> 2011-09-01 00:00:00
9 -> 2011-10-01 00:00:00
10 -> 2011-11-01 00:00:00
11 -> 2012-12-01 00:00:00
12 -> 2012-01-01 00:00:00
13 -> 2012-02-01 00:00:00
14 -> 2012-03-01 00:00:00
15 -> 2012-04-01 00:00:00
16 -> 2012-05-01 00:00:00
17 -> 2012-06-01 00:00:00
18 -> 2012-07-01 00:00:00
19 -> 2012-08-01 00:00:00
20 -> 2012-09-01 00:00:00
얼마 전에 나는 a date또는 datetime.
주의 사항 : day새 달에 사용할 수없는 경우 실패합니다 . 나는 day == 1항상 날짜 개체에 이것을 사용합니다 .
Python 3.x :
def increment_month(d, add=1):
return date(d.year+(d.month+add-1)//12, (d.month+add-1) % 12+1, 1)
Python 2.7의 경우 정수 나눗셈이 암시되기 때문에 //12를로 변경하십시오 /12.
최근에 스크립트가 이러한 유용한 전역을 얻기 시작했을 때 기본 파일에서 이것을 사용했습니다.
MONTH_THIS = datetime.date.today()
MONTH_THIS = datetime.date(MONTH_THIS.year, MONTH_THIS.month, 1)
MONTH_1AGO = datetime.date(MONTH_THIS.year+(MONTH_THIS.month-2)//12,
(MONTH_THIS.month-2) % 12+1, 1)
MONTH_2AGO = datetime.date(MONTH_THIS.year+(MONTH_THIS.month-3)//12,
(MONTH_THIS.month-3) % 12+1, 1)
import datetime
date_str = '08/01/2018'
format_str = '%d/%m/%Y'
datetime_obj = datetime.datetime.strptime(date_str, format_str)
datetime_obj.replace(month=datetime_obj.month-1)
특별한 라이브러리가 필요없는 간단한 솔루션입니다.
((date.month+delta-1) % 12)+1작품과 수단은if not m: m = 12제거 얻을 수 있습니다