This question already has answers here:
Convert string "Jun 1 2005 1:33PM" into datetime
(26 answers)
Closed 7 years ago.
I have a raw input from the user such as "2015-01-30"...for the query I am using, the date has to be inputed as a string as such "yyyy-mm-dd".
I would like to increment the date by 1 month at end of my loop s.t "2015-01-30" becomes "2015-02-27" (ideally the last business day of the next month). I was hoping someone could help me; I am using PYTHON, the reason I want to convert to datetime is I found a function to add 1 month.
Ideally my two questions to be answered are (in Python):
1) how to convert string "yyyy-mm-dd" into a python datetime and convert back into string after applying a timedelta function
2) AND/or how to add 1 month to string "yyyy-mm-dd"
Maybe these examples will help you get an idea:
from dateutil.relativedelta import relativedelta
import datetime
date1 = datetime.datetime.strptime("2015-01-30", "%Y-%m-%d").strftime("%d-%m-%Y")
print(date1)
today = datetime.date.today()
print(today)
addMonths = relativedelta(months=3)
future = today + addMonths
print(future)
If you import datetime it will give you more options in managing date and time variables. In my example above I have some example code that will show you how it works.
It is also very usefull if you would for example would like to add a x number of days, months or years to a certain date.
Edit:
To answer you question below this post I would suggest you to look at "calendar"
For example:
import calendar
january2012 = calendar.monthrange(2002,1)
print(january2012)
february2008 = calendar.monthrange(2008,2)
print(february2008)
This return you the first workday of the month, and the number of days of the month.
With that you can calculate what was the last workday of the month.
Here is more information about it: Link
Also have a loook here, looks what you might could use: Link
converting string 'yyyy-mm-dd' into datetime/date python
from datetime import date
date_string = '2015-01-30'
now = date(*map(int, date_string.split('-')))
# or now = datetime.strptime(date_string, '%Y-%m-%d').date()
the last business day of the next month
from datetime import timedelta
DAY = timedelta(1)
last_bday = (now.replace(day=1) + 2*31*DAY).replace(day=1) - DAY
while last_bday.weekday() > 4: # Sat, Sun
last_bday -= DAY
print(last_bday)
# -> 2015-02-27
It doesn't take into account holidays.
You can use a one-liner, that takes the datetime, adds a month (using a defined function), and converts back to a string:
x = add_months(datetime.datetime(*[int(item) for item in x.split('-')]), 1).strftime("%Y-%m-%d")
>>> import datetime, calendar
>>> x = "2015-01-30"
>>> x = add_months(datetime.datetime(*[int(item) for item in x.split('-')]), 1).strftime("%Y-%m-%d")
>>> x
'2015-02-28'
>>>
add_months:
def add_months(sourcedate,months):
month = sourcedate.month - 1 + months
year = sourcedate.year + month / 12
month = month % 12 + 1
day = min(sourcedate.day,calendar.monthrange(year,month)[1])
return datetime.date(year,month,day)
To convert a string of that format into a Python date object:
In [1]: import datetime
In [2]: t = "2015-01-30"
In [3]: d = datetime.date(*(int(s) for s in t.split('-')))
In [4]: d
Out[4]: datetime.date(2015, 1, 30)
To move forward to the last day of next month:
In [4]: d
Out[4]: datetime.date(2015, 1, 30)
In [5]: new_month = (d.month + 1) if d.month != 12 else 1
In [6]: new_year = d.year if d.month != 12 else d.year + 1
In [7]: import calendar
In [8]: new_day = calendar.monthrange(new_year, new_month)[1]
In [9]: d = d.replace(year=new_year,month=new_month,day=new_day)
In [10]: d
Out[10]: datetime.date(2015, 2, 28)
And this datetime.date object can be easily converted to a 'YYYY-MM-DD' string:
In [11]: str(d)
Out[11]: '2015-02-28'
EDIT:
To get the last business day (i.e. Monday-Friday) of the month:
In [8]: new_day = calendar.monthrange(new_year, new_month)[1]
In [9]: d = d.replace(year=new_year,month=new_month,day=new_day)
In [10]: day_of_the_week = d.isoweekday()
In [11]: if day_of_the_week > 5:
....: adj_new_day = new_day - (day_of_the_week - 5)
....: d = d.replace(day=adj_new_day)
....:
In [11]: d
Out[11]: datetime.date(2015, 2, 27)
Related
I'm quite lost and I'm in need of trying to format some code so it ends up having dashes in the date. I can get 3, 12, 28 but I can't get 3-12-28. I am a super new beginner so I'm quite lost at the moment.
year = 3
month = 12
day = 28
print(date)
Try
print("{0}-{1}-{2}".format(year,month,day))
You could use datetime to format the result
import datetime
year = 3
month = 12
day = 28
dt = (datetime.date(year, month, day))
print(dt)
the result will be 0003-12-28
if you want more examples of datetime you could take a look at https://docs.python.org/2/library/datetime.html#
As you say you are new to python you can concatenate the strings together.
year = 3
month = 12
day = 28
date = year + "-" + month + "-" + day
print(date)
Alternatively you can use format to set the variables in your required format.
print(f"{year}-{month}-{day}")
Another method is to use datetime if you are using todays date
import datetime
today = datetime.date.today()
print(today)
Please what's wrong with my code:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)
Display "2013-01-01 00:00:00", Thanks.
A week number is not enough to generate a date; you need a day of the week as well. Add a default:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
print(r)
The -1 and -%w pattern tells the parser to pick the Monday in that week. This outputs:
2013-07-01 00:00:00
%W uses Monday as the first day of the week. While you can pick your own weekday, you may get unexpected results if you deviate from that.
See the strftime() and strptime() behaviour section in the documentation, footnote 4:
When used with the strptime() method, %U and %W are only used in calculations when the day of the week and the year are specified.
Note, if your week number is a ISO week date, you'll want to use %G-W%V-%u instead! Those directives require Python 3.6 or newer.
In Python 3.8 there is the handy datetime.date.fromisocalendar:
>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1) # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)
In older Python versions (3.7-) the calculation can use the information from datetime.date.isocalendar to figure out the week ISO8601 compliant weeks:
from datetime import date, timedelta
def monday_of_calenderweek(year, week):
first = date(year, 1, 1)
base = 1 if first.isocalendar()[1] == 1 else 8
return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))
Both works also with datetime.datetime.
To complete the other answers - if you are using ISO week numbers, this string is appropriate (to get the Monday of a given ISO week number):
import datetime
d = '2013-W26'
r = datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)
%G, %V, %u are ISO equivalents of %Y, %W, %w, so this outputs:
2013-06-24 00:00:00
Availabe in Python 3.6+; from docs.
import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res
Adding of 1 as week day will yield exact current week start. Adding of timedelta(days=6) will gives you the week end.
datetime.datetime(2018, 7, 23)
If anyone is looking for a simple function that returns all working days (Mo-Fr) dates from a week number consider this (based on accepted answer)
import datetime
def weeknum_to_dates(weeknum):
return [datetime.datetime.strptime("2021-W"+ str(weeknum) + str(x), "%Y-W%W-%w").strftime('%d.%m.%Y') for x in range(-5,0)]
weeknum_to_dates(37)
Output:
['17.09.2021', '16.09.2021', '15.09.2021', '14.09.2021', '13.09.2021']
In case you have the yearly number of week, 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)
Another solution which worked for me that accepts series data as opposed to strptime only accepting single string values:
#fw_to_date
import datetime
import pandas as pd
# fw is input in format 'YYYY-WW'
# Add weekday number to string 1 = Monday
fw = fw + '-1'
# dt is output column
# Use %G-%V-%w if input is in ISO format
dt = pd.to_datetime(fw, format='%Y-%W-%w', errors='coerce')
Here's a handy function including the issue with zero-week.
This question already has answers here:
Return datetime object of previous month
(23 answers)
Closed 6 years ago.
I need to get the first day of last month from any date.
I know that I can use monthdelta(datetime(2010,3,30), -1) to get last month, but it doesn't return the first day.
This can be done by first calculating the first day of current month ( or any given date ), then subtracting it with datetime.timedelta(days=1) which gives you the last day of previous month.
For demonstration, here is a sample code:
import datetime
def get_lastday(current):
_first_day = current.replace(day=1)
prev_month_lastday = _first_day - datetime.timedelta(days=1)
return prev_month_lastday.replace(day=1)
Try like this. With using datetime and datetutil.
(if datetutil not available for you install pip install python-dateutil)
In [1]: from datetime import datetime
In [2]: import dateutil.relativedelta
In [3]: today_date = datetime.now().date()
In [4]: today_date
Out[1]: datetime.date(2016, 7, 5)
In [5]: last_month = today_date - dateutil.relativedelta.relativedelta(months=1)
In [6]: last_mont_first_date = last_month.replace(day=1)
In [7]: last_mont_first_date
Out[2]: datetime.date(2016, 6, 1)
Input:
datetime.date(2016, 7, 5)
Output
datetime.date(2016, 6, 1)
Try this :
from datetime import date
d = date.today()
d.replace(
year=d.year if d.month > 1 else d.year - 1,
month=d.month - 1 if d.month > 1 else 12,
day=1
)
I am trying to get the date delta by subtracting today's date from the nth day of the next month.
delta = nth_of_next_month - todays_date
print delta.days
How do you get the date object for the 1st (or 2nd, 3rd.. nth) day of the next month. I tried taking the month number from the date object and increasing it by 1. Which is obviously a dumb idea because 12 + 1 = 13. I also tried adding one month to today and tried to get to the first of the month. I am sure that there is a much more efficient way of doing this.
The dateutil library is useful for this:
from dateutil.relativedelta import relativedelta
from datetime import datetime
# Where day is the day you want in the following month
dt = datetime.now() + relativedelta(months=1, day=20)
This should be straightforward unless I'm missing something in your question:
import datetime
now = datetime.datetime.now()
nth_day = 5
next_month = now.month + 1 if now.month < 12 else 1 # February
year = now.year if now.month < 12 else now.year+1
nth_of_next_month = datetime.datetime(year, next_month, nth_day)
print(nth_of_next_month)
Result:
2014-02-05 00:00:00
Using dateutil as suggested in another answer is a much better idea than this, though.
Another alternative is to use delorean library:
Delorean is a library that provides easy and convenient datetime
conversions in Python.
>>> from delorean import Delorean
>>> d = Delorean()
>>> d.next_month()
Delorean(datetime=2014-02-15 18:51:14.325350+00:00, timezone=UTC)
>>> d.next_month().next_day(2)
Delorean(datetime=2014-02-17 18:51:14.325350+00:00, timezone=UTC)
My approach to calculating the next month without external libraries:
def nth_day_of_next_month(dt, n):
return dt.replace(
year=dt.year + (dt.month // 12), # +1 for december, +0 otherwise
month=(dt.month % 12) + 1, # december becomes january
day=n)
This works for both datetime.datetime() and datetime.date() objects.
Demo:
>>> import datetime
>>> def nth_day_of_next_month(dt, n):
... return dt.replace(year=dt.year + (dt.month // 12), month=(dt.month % 12) + 1, day=n)
...
>>> nth_day_of_next_month(datetime.datetime.now(), 4)
datetime.datetime(2014, 2, 4, 19, 20, 51, 177860)
>>> nth_day_of_next_month(datetime.date.today(), 18)
datetime.date(2014, 2, 18)
Without using any external library, this can be achived as follows
from datetime import datetime, timedelta
def nth_day_of_next_month(n):
today = datetime.now()
next_month_dt = today + timedelta(days=32-today.day)
return next_month_dt.replace(day=n)
In Sweden we sometimes use a strange date format, for example New Year is the 31/12. If I have this format as a string ,which can be any date between 1/1 and 31/12, and if we assume that it is this year, how do I get into a standard date format using Python (format as 2012-01-01 and 2012-12-31) that can be sore in be stored as a date in a mySQL database.
Simply split the two values, map them to integers and update a datetime.date() instance:
import datetime
day, month = map(int, yourvalue.split('/'))
adate = datetime.date.today().replace(month=month, day=day)
By using datetime.date.today() we get the current year.
Demo:
>>> import datetime
>>> somevalue = '31/12'
>>> day, month = map(int, somevalue.split('/'))
>>> datetime.date.today().replace(month=month, day=day)
datetime.date(2012, 12, 31)
>>> someothervalue = '1/1'
>>> day, month = map(int, someothervalue.split('/'))
>>> datetime.date.today().replace(month=month, day=day)
datetime.date(2012, 1, 1)
Alternatively, you could use the datetime.strptime() method to parse these dates, but you'll have to manually correct the year afterwards (it'll use 1900 as the default if no year is being parsed):
adate = datetime.datetime.strptime(yourvalue, '%d/%m').date()
adate = adate.replace(year=datetime.date.today().year)
There is nothing strange about this format :)
You can use the datetime module:
import datetime
d = datetime.datetime.strptime('31/12', '%d/%m').date().replace(year=2012)
print d
>> datetime.date(2012, 12, 31)