I am trying to get last month and current year in the format: July 2016.
I have tried (but that didn't work) and it does not print July but the number:
import datetime
now = datetime.datetime.now()
print now.year, now.month(-1)
If you're manipulating dates then the dateutil library is always a great one to have handy for things the Python stdlib doesn't cover easily.
First, install the dateutil library if you haven't already:
pip install python-dateutil
Next:
from datetime import datetime
from dateutil.relativedelta import relativedelta
# Returns the same day of last month if possible otherwise end of month
# (eg: March 31st->29th Feb an July 31st->June 30th)
last_month = datetime.now() - relativedelta(months=1)
# Create string of month name and year...
text = format(last_month, '%B %Y')
Gives you:
'July 2016'
now = datetime.datetime.now()
last_month = now.month-1 if now.month > 1 else 12
last_year = now.year - 1
to get the month name you can use
"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split()[last_month-1]
An alternative solution using Pandas which converts today to a monthly period and then subtracts one (month). Converted to desired format using strftime.
import datetime as dt
import pandas as pd
>>> (pd.Period(dt.datetime.now(), 'M') - 1).strftime('%B %Y')
u'July 2016'
You can use just the Python datetime library to achieve this.
Explanation:
Replace day in today's date with 1, so you get date of first day of this month.
Doing - timedelta(days=1) will give last day of previous month.
format and use '%B %Y' to convert to required format.
import datetime as dt
format(dt.date.today().replace(day=1) - dt.timedelta(days=1), '%B %Y')
>>>'June-2019'
from datetime import date, timedelta
last_month = date.today().replace(day=1) - timedelta(1)
last_month.strftime("%B %Y")
date.today().replace(day=1) gets the first day of current month, substracting 1 day will get last day of last month
def subOneMonth(dt):
day = dt.day
res = dt.replace(day=1) - datetime.timedelta(days =1)
try:
res.replace(day= day)
except ValueError:
pass
return res
print subOneMonth(datetime.datetime(2016,07,11)).strftime('%d, %b %Y')
11, Jun 2016
print subOneMonth(datetime.datetime(2016,01,11)).strftime('%d, %b %Y')
11, Dec 2015
print subOneMonth(datetime.datetime(2016,3,31)).strftime('%d, %b %Y')
29, Feb 2016
from datetime import datetime, timedelta, date, time
#Datetime: 1 month ago
datetime_to = datetime.now().replace(day=15) - timedelta(days=30 * 1)
#Date : 2 months ago
date_to = date.today().replace(day=15) - timedelta(days=30 * 2)
#Date : 12 months ago
date_to = date.today().replace(day=15) - timedelta(days=30 *12)
#Accounting standards: 13 months ago of pervious day
date_ma = (date.today()-timedelta(1)).replace(day=15)-timedelta(days=30*13)
yyyymm = date_ma.strftime('%Y%m') #201909
yyyy = date_ma.strftime('%Y') #2019
#Error Range Test
from datetime import datetime, timedelta, date, time
import pandas as pd
for i in range(1,120):
pdmon = (pd.Period(dt.datetime.now(), 'M')-i).strftime('%Y%m')
wamon = (date.today().replace(day=15)-timedelta(days=30*i)).strftime('%Y%m')
if pdmon != wamon:
print('Incorrect %s months ago:%s,%s' % (i,pdmon,wamon))
break
#Incorrect 37 months ago:201709,201710
import datetime as dt
.replace(day=1) replaces today's date with the first day of the month, simple
subtracting timedelta(1) subtracts 1 day, giving the last day of the previous month
last_month = dt.datetime.today().replace(day=1) - dt.timedelta(1)
user wanted the word July, not the 6th month so updating %m to %B
last_month.strftime("%Y, %B")
Related
Using scrapy and python I am collecting tour dates from webpages.
The year is not present in the field e.g. '11th November' or '21st January' which is fine because I can add a year doing the string-to-date conversion using the following code:
def sortdate(self, mydate):
newdate = datetime.strptime(
re.sub(r"\b([0123]?[0-9])(st|th|nd|rd)\b", r"\1", mydate) + " " + str(datetime.now().year),
"%d %B %Y")
return newdate
This turns '11th November' into 'datetime.datetime(2019, 11, 11, 0, 0)'
which is perfect.
My issue now is that it adds 2019 to everything, even next year's dates. So I need to assess today's date (today is 13th November 2019) and then when it does the conversation it will add the correct year. e.g. '11th January' will get 2020 but '12th November' would now get 2020 as well (since today's date has passed the threshold).
You asked for help modifying the date output depending on whether the input day has has already occurred on this year's calendar. In order to do that, I put most of your logic (good job on that, btw) into a function that we can use twice.
We'll run it once with the current year, and compare the output to datetime.now(), and if the date is less than now() then it's in the past. In that case, we'll run the same logic again, but with this year +1.
import re
from datetime import datetime
def set_date(date, year):
regex_date = re.sub( r"\b([0123]?[0-9])(st|th|nd|rd)\b", r"\1", date)
new_date = datetime.strptime(f"{regex_date} {year}", "%d %B %Y")
return new_date
def sort_date(date):
now = datetime.now()
new_date = set_date(date, now.year)
if new_date < now:
new_date = set_date(date, now.year + 1)
return new_date
this_year = sort_date("20 November")
next_year = sort_date("1 November")
print(this_year)
print(next_year)
Outputs:
2019-11-20 00:00:00
2020-11-01 00:00:00
Suppose today is August 28, 2019 i want timestamp of July 1,12:00:00 AM and July 31,23:59:59 PM. In general, I want the previous month date and time irrespective of year.
Alternatively with no additional modules:
from datetime import datetime, timedelta
now = datetime.now()
print(now)
firstOfThisMonth = now.replace(day=1)
print(firstOfThisMonth)
endOfLastMonth = firstOfThisMonth-timedelta(days=1)
print(endOfLastMonth)
firstOfLastMonth = endOfLastMonth.replace(day=1)
print(firstOfLastMonth)
print(firstOfLastMonth.replace(hour=0, minute=0, second=0, microsecond=0))
print(endOfLastMonth.replace(hour=23, minute=59, second=59, microsecond=0))
Outputs the following
2019-08-28 07:36:38.768223
2019-08-01 07:36:38.768223
2019-07-31 07:36:38.768223
2019-07-01 07:36:38.768223
2019-07-01 00:00:00
2019-07-31 23:59:59
The following should work for both Python 3x and Python2.7
from datetime import date
from dateutil.relativedelta import relativedelta
today = date.today()
d = today - relativedelta(months=1)
first_day = date(d.year, d.month, 1)
first_day.strftime('%A %d %B %Y')
#returns first date of the previous month - datetime.date(2019, 7, 1)
last_day = date(today.year, today.month, 1) - relativedelta(days=1)
last_day.strftime('%A %d %B %Y')
# returns the last date of the previous month - datetime.date(2019, 7, 31)
Note - The above code only returns the first and last date, not the time. I don't really understand why can't you just hard code the time in milliseconds since it will always be fixed, irrespective of the date.
I want to get the 20th of previous month, given the current_date()
I am trying to use time.strftime but not able to subtract the value from it.
timestr = time.strftime("%Y-(%m-1)%d")
This is giving me error. The expected output is 2019-03-20 if my current_date is in April. Not sure how to go about it.
I read the posts from SO and most of them address getting the first day / last day of the month. Any help would be appreciated.
from datetime import date, timedelta
today = date.today()
last_day_prev_month = today - timedelta(days=today.day)
twenty_prev_month = last_day_prev_month.replace(day=20)
print(twenty_prev_month) # 2019-03-20
Use datetime.replace
import datetime
current_date = datetime.date.today()
new_date = current_date.replace(
month = current_date.month - 1,
day = 20
)
print(new_date)
#2019-03-20
Edit
That won't work for Jan so this is a workaround:
import datetime
current_date = datetime.date(2019, 2, 17)
month = current_date.month - 1
year = current_date.year
if not month:
month, year = 12, year - 1
new_date = datetime.date(year=year, month=month, day=20)
I imagine it is the way dates are parsed. It is my understanding that with your code it is looking for
2019-(03-1)20 or 2019-(12-1)15, etc..
Because the %y is not a variable, but a message about how the date is to be expected within a string of text, and other characters are what should be expected, but not processed (like "-")
This seems entirely not what you are going for. I would just parse the date like normal and then reformat it to be a month earlier:
import datetime
time = datetime.datetime.today()
print(time)
timestr = time.strftime("%Y-%m-%d")
year, month, day = timestr.split("-")
print("{}-{}-{}".format(year, int(month)-1, day))
This would be easier with timedelta objects, but sadly there isn't one for months, because they are of various lengths.
To be more robust if a new year is involved:
import datetime
time = datetime.datetime.today()
print(time)
timestr = time.strftime("%Y-%m-%d")
year, month, day = timestr.split("-")
if month in [1, "01", "1"]: # I don't remember how January is represented
print("{}-{}-{}".format(int(year) - 1, 12, day)) # use December of last year
else:
print("{}-{}-{}".format(year, int(month)-1, day))
This will help:
from datetime import date, timedelta
dt = date.today() - timedelta(30)// timedelta(days No.)
print('Current Date :',date.today())
print(dt)
It is not possible to do math inside a string passed to time.strftime, but you can do something similar to what you're asking very easily using the time module
in Python 3
# Last month
t = time.gmtime()
print(f"{t.tm_year}-{t.tm_mon-1}-20")
or in Python 2
print("{0}-{1}-{2}".format(t.tm_year, t.tm_mon -1, 20))
If you have fewer constraints, you can just use the datetime module instead.
You could use datetime, dateutil or arrow to find the 20th day of the previous month. See examples below.
Using datetime:
from datetime import date
d = date.today()
month, year = (d.month-1, d.year) if d.month != 1 else (12, d.year-1)
last_month = d.replace(day=20, month=month, year=year)
print(last_month)
Using datetime and timedelta:
from datetime import date
from datetime import timedelta
d = date.today()
last_month = (d - timedelta(days=d.day)).replace(day=20)
print(last_month)
Using datetime and dateutil:
from datetime import date
from dateutil.relativedelta import relativedelta # pip install python-dateutil
d = date.today()
last_month = d.replace(day=20) - relativedelta(months=1)
print(last_month)
Using arrow:
import arrow # pip install arrow
d = arrow.now()
last_month = d.shift(months=-1).replace(day=20).datetime.date()
print(last_month)
I want to determine the difference between a date string and the current time.
The problem is that the time string does not contain a year (But the current datetime does, so that would be make trouble on year change?)
Here's my current code:
date_parsed = datetime.strptime('Fri Apr 27 19:09:53', '%a %b %d %H:%M:%S')
current_time = datetime.now()
We can assume that date_parsed occurred during the last 365 days, right?
In that case, use .replace() to change the year of that date, compare it to the current date, and adapt the year according to the result of that comparison: if the date is after now, then the parsed date should be adapted, otherwhise, it's ok:
from datetime import datetime
current_time = datetime.now()
date_parsed = datetime.strptime('Fri Apr 27 14:09:53', '%a %b %d %H:%M:%S').replace(year=current_time.year)
if date_parsed > current_time:
date_parsed = date_parsed.replace(year=current_time.year - 1)
print(date_parsed, current_time, current_time - date_parsed)
E.g. with a date in "the past":
2018-04-27 14:09:53 2018-04-27 18:28:10.484371 4:18:17.484371
E.g. with a date in the "future":
2017-04-30 14:09:53 2018-04-27 18:30:48.864598 362 days, 4:20:55.864598
You could do it with total_seconds and modulo arithmetic, but then I think you have issues with things like leap years. Probably the best way is to try two replacements:
tdiff = current_time - date_parsed.replace(year=current_time.year)
if tdiff.days < 0:
tdiff = current_time - date_parsed.replace(year=current_time.year-1)
You can use .strftime() method to synchronize your string time and current time as following:
from datetime import datetime
date_parsed = datetime.strptime('Fri Apr 27 19:09:53', '%a %b %d %H:%M:%S')
current_time = datetime.now().strftime("%m-%d %H:%M:%S")
date_ = date_parsed.strftime("%m-%d %H:%M:%S")
Say I have a week number of a given year (e.g. week number 6 of 2014).
How can I convert this to the date of the Monday that starts that week?
One brute force solution I thought of would be to go through all Mondays of the year:
date1 = datetime.date(1,1,2014)
date2 = datetime.date(12,31,2014)
def monday_range(date1,date2):
while date1 < date2:
if date1.weekday() == 0:
yield date1
date1 = date1 + timedelta(days=1)
and store a hash from the first to the last Monday of the year, but this wouldn't do it, since, the first week of the year may not contain a Monday.
You could just feed the data into time.asctime().
>>> import time
>>> week = 6
>>> year = 2014
>>> atime = time.asctime(time.strptime('{} {} 1'.format(year, week), '%Y %W %w'))
>>> atime
'Mon Feb 10 00:00:00 2014'
EDIT:
To convert this to a datetime.date object:
>>> datetime.datetime.fromtimestamp(time.mktime(atime)).date()
datetime.date(2014, 2, 10)
All about strptime \ strftime:
https://docs.python.org/2/library/datetime.html
mytime.strftime('%U') #for W\C Monday
mytime.strftime('%W') #for W\C Sunday
Sorry wrong way around
from datetime import datetime
mytime=datetime.strptime('2012W6 MON'. '%YW%U %a')
Strptime needs to see both the year and the weekday to do this. I'm assuming you've got weekly data so just add 'mon' to the end of the string.
Enjoy
A simple function to get the Monday, given a date.
def get_monday(dte):
return dte - datetime.timedelta(days = dte.weekday())
Some sample output:
>>> get_monday(date1)
datetime.date(2013, 12, 30)
>>> get_monday(date2)
datetime.date(2014, 12, 29)
Call this function within your loop.
We can just add the number of weeks to the first day of the year.
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)
To piggyback and give a different version of the answer #anon582847382 gave, you can do something like the below code if you're creating a function for it and the week number is given like "11-2023":
import time
from datetime import datetime
def get_date_from_week_number(str_value):
temp_str = time.asctime(time.strptime('{} {} 1'.format(str_value[3:7], str_value[0:2]), '%Y %W %w'))
return datetime.strptime(temp_str, '%a %b %d %H:%M:%S %Y').date()