Reputation: 3179
I am trying to get the date of the previous month with python. Here is what i've tried:
str( time.strftime('%Y') ) + str( int(time.strftime('%m'))-1 )
However, this way is bad for 2 reasons: First it returns 20122 for the February of 2012 (instead of 201202) and secondly it will return 0 instead of 12 on January.
I have solved this trouble in bash with
echo $(date -d"3 month ago" "+%G%m%d")
I think that if bash has a built-in way for this purpose, then python, much more equipped, should provide something better than forcing writing one's own script to achieve this goal. Of course i could do something like:
if int(time.strftime('%m')) == 1:
return '12'
else:
if int(time.strftime('%m')) < 10:
return '0'+str(time.strftime('%m')-1)
else:
return str(time.strftime('%m') -1)
I have not tested this code and i don't want to use it anyway (unless I can't find any other way:/)
Thanks for your help!
Upvotes: 238
Views: 401024
Reputation: 36464
datetime and the datetime.timedelta classes are your friend.
Like this:
import datetime
today = datetime.date.today()
first = today.replace(day=1)
last_month = first - datetime.timedelta(days=1)
print(last_month.strftime("%Y%m"))
201202
is printed.
Upvotes: 509
Reputation: 147
It's more easier to use the timedelta module from datetime.
from datetime import datetime, timedelta
now = datetime.now()
lastmonth_date = now - timedelta(days=now.day)
Now, to get last month's number you can use:
lastmonth = lastmonth_date.strftime("%m")
To get the year,
lastmonth_year = lastmonth_date.strftime("%Y")
Upvotes: -1
Reputation: 741
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
#Months(0-12) (1 for Previous month)
#last day of (n) previous month (n=months)
day = datetime(2023, 1, 13)
n = 1
lastDayMonth = ((day - relativedelta(months=n) + relativedelta(day=31)).date());
#First day of previous month (n=months=1)
firstDayMonth = ((day - relativedelta(months=n) + relativedelta(day=1)).date());
print("Last Day of Month - "+ str(lastDayMonth))
print("First Day of Month - "+ str(firstDayMonth))
#Last business day (Friday) of prev (n) month if last day on weekend
lastBusDay = (lastDayMonth - timedelta(max(1,(lastDayMonth.weekday() + 6) % 7 - 3))) if lastDayMonth.weekday() in (5,6) else lastDayMonth
print("Last Business Day of Month - " + str(lastBusinessDay))
print()
Upvotes: 0
Reputation: 91
from datetime import datetime, timedelta, time, timezone
current_time = datetime.now(timezone.utc)
last_day_previous_month = datetime.combine(current_time.replace(day=1), time.max) - timedelta(days=1)
first_day_previous_month = datetime.combine(last_day_previous_month, time.min).replace(day=1)
Output:
first_day_previous_month: 2022-02-01 00:00:00
last_day_previous_month: 2022-02-28 23:59:59.999999
Upvotes: 2
Reputation: 31
Explicit way:
import datetime
result = (datetime.datetime.today().month - 2) % 12 + 1
The problem is how to transfer month
[1, 2, 3, ..., 12] to [12, 1, 2, ..., 11].
Step1: month = month - 1
transfer [1, 2, 3, ..., 12] to [0, 1, 2, ..., 11].
Step2: month = (month - 1) % 12
transfer [0, 1, 2, ..., 11] to [11, 0, 1, ..., 10].
Step3: month = month + 1
transfer [11, 0, 1, ..., 10] to [12, 1, 2, ..., 11].
So, the result is result = (month - 2) % 12 + 1
Upvotes: 3
Reputation: 308
import pandas as pd
lastmonth = int(pd.to_datetime("today").strftime("%Y%m"))-1
print(lastmonth)
202101
from datetime import date, timedelta
YYYYMM = (date.today().replace(day=1)-timedelta(days=1)).strftime("%Y%m")
Upvotes: -2
Reputation: 403
You can do it as below:
from datetime import datetime, timedelta
last_month = (datetime.now() - timedelta(days=32)).strftime("%Y%m")
Upvotes: -1
Reputation: 403
You might have come here because you're working with Jython in NiFi. This is how I ended up implementing it. I deviated a little from this answer by Robin Carlo Catacutan because accessing last_day_of_prev_month.day wasn't possible due to a Jython datatype issue explained here that for some reason seems to exist in NiFi'S Jython but not in vanilla Jython.
from datetime import date, timedelta
import calendar
flowFile = session.get()
if flowFile != None:
first_weekday_in_prev_month, num_days_in_prev_month = calendar.monthrange(date.today().year,date.today().month-1)
last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1)
first_day_of_prev_month = date.today().replace(day=1) - timedelta(days=num_days_in_prev_month)
last_day_of_prev_month = str(last_day_of_prev_month)
first_day_of_prev_month = str(first_day_of_prev_month)
flowFile = session.putAllAttributes(flowFile, {
"last_day_of_prev_month": last_day_of_prev_month,
"first_day_of_prev_month": first_day_of_prev_month
})
session.transfer(flowFile, REL_SUCCESS)
Upvotes: 1
Reputation: 13963
Simple, one liner:
import datetime as dt
previous_month = (dt.date.today().replace(day=1) - dt.timedelta(days=1)).month
Upvotes: 13
Reputation: 300
There is a high level library dateparser
that can determine the past date given natural language, and return the corresponding Python datetime
object
from dateparser import parse
parse('4 months ago')
Upvotes: 0
Reputation: 18375
With the Pendulum very complete library, we have the subtract
method (and not "subStract"):
import pendulum
today = pendulum.datetime.today() # 2020, january
lastmonth = today.subtract(months=1)
lastmonth.strftime('%Y%m')
# '201912'
We see that it handles jumping years.
The reverse equivalent is add
.
https://pendulum.eustace.io/docs/#addition-and-subtraction
Upvotes: 6
Reputation: 13679
For someone who got here and looking to get both the first and last day of the previous month:
from datetime import date, timedelta
last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1)
start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day)
# For printing results
print("First day of prev month:", start_day_of_prev_month)
print("Last day of prev month:", last_day_of_prev_month)
Output:
First day of prev month: 2019-02-01
Last day of prev month: 2019-02-28
Upvotes: 32
Reputation: 1823
You should use dateutil. With that, you can use relativedelta, it's an improved version of timedelta.
>>> import datetime
>>> import dateutil.relativedelta
>>> now = datetime.datetime.now()
>>> print now
2012-03-15 12:33:04.281248
>>> print now + dateutil.relativedelta.relativedelta(months=-1)
2012-02-15 12:33:04.281248
Upvotes: 126
Reputation: 1345
Its very easy and simple. Do this
from dateutil.relativedelta import relativedelta
from datetime import datetime
today_date = datetime.today()
print "todays date time: %s" %today_date
one_month_ago = today_date - relativedelta(months=1)
print "one month ago date time: %s" % one_month_ago
print "one month ago date: %s" % one_month_ago.date()
Here is the output: $python2.7 main.py
todays date time: 2016-09-06 02:13:01.937121
one month ago date time: 2016-08-06 02:13:01.937121
one month ago date: 2016-08-06
Upvotes: 10
Reputation: 41
def prev_month(date=datetime.datetime.today()):
if date.month == 1:
return date.replace(month=12,year=date.year-1)
else:
try:
return date.replace(month=date.month-1)
except ValueError:
return prev_month(date=date.replace(day=date.day-1))
Upvotes: 3
Reputation: 10208
Building off the comment of @J.F. Sebastian, you can chain the replace()
function to go back one "month". Since a month is not a constant time period, this solution tries to go back to the same date the previous month, which of course does not work for all months. In such a case, this algorithm defaults to the last day of the prior month.
from datetime import datetime, timedelta
d = datetime(2012, 3, 31) # A problem date as an example
# last day of last month
one_month_ago = (d.replace(day=1) - timedelta(days=1))
try:
# try to go back to same day last month
one_month_ago = one_month_ago.replace(day=d.day)
except ValueError:
pass
print("one_month_ago: {0}".format(one_month_ago))
Output:
one_month_ago: 2012-02-29 00:00:00
Upvotes: 1
Reputation: 671
Just for fun, a pure math answer using divmod. Pretty inneficient because of the multiplication, could do just as well a simple check on the number of month (if equal to 12, increase year, etc)
year = today.year
month = today.month
nm = list(divmod(year * 12 + month + 1, 12))
if nm[1] == 0:
nm[1] = 12
nm[0] -= 1
pm = list(divmod(year * 12 + month - 1, 12))
if pm[1] == 0:
pm[1] = 12
pm[0] -= 1
next_month = nm
previous_month = pm
Upvotes: 1
Reputation: 3168
from datetime import date, timedelta
first_day_of_current_month = date.today().replace(day=1)
last_day_of_previous_month = first_day_of_current_month - timedelta(days=1)
print "Previous month:", last_day_of_previous_month.month
Or:
from datetime import date, timedelta
prev = date.today().replace(day=1) - timedelta(days=1)
print prev.month
Upvotes: 60
Reputation: 4223
Building on bgporter's answer.
def prev_month_range(when = None):
"""Return (previous month's start date, previous month's end date)."""
if not when:
# Default to today.
when = datetime.datetime.today()
# Find previous month: https://stackoverflow.com/a/9725093/564514
# Find today.
first = datetime.date(day=1, month=when.month, year=when.year)
# Use that to find the first day of this month.
prev_month_end = first - datetime.timedelta(days=1)
prev_month_start = datetime.date(day=1, month= prev_month_end.month, year= prev_month_end.year)
# Return previous month's start and end dates in YY-MM-DD format.
return (prev_month_start.strftime('%Y-%m-%d'), prev_month_end.strftime('%Y-%m-%d'))
Upvotes: 9