So this code what I want:
import datetime
d = datetime.date.today()
three_months_ago = d - timedelta(months=3)
However, as we know, the 'months' param does not exist in timedelta.
I admit I can program like this to achieve the goal:
if d.month > 3:
three_months_ago = datetime.date(d.year, d.month-3, d.day)
else:
three_months_ago = datetime.date(d.year-1, d.month-3+12, d.day)
But this seems really stupid...
Can you guys tell me how to realize this smartly?
This could help:
>>>from dateutil.relativedelta import relativedelta
>>>import datetime
>>>datetime.date.today()
datetime.date(2016, 3, 10)
>>>datetime.date.today() - relativedelta(months=3)
datetime.date(2015, 12, 10)
You can use relativedelta() to add or subtract weeks and years too.
Numpy's timedelta has months support, ie:
np.timedelta64(3, 'M')
Related
I understand there's an package "date" from "datetime"
for solving "Calculate numbers of days between two given date", but this is not what I am looking for
Let me give an example to further describe my question.
let says:10 days and the baseline is 2021/09/09
I want to know the date before 10 days 8/30 is clearly the answer I am looking for
It might be an easy question. still needs for help. Thanks
This might just work:
from datetime import date, timedelta
day1 = date(2021, 9, 9)
difference = timedelta(days=10)
day2 = day1 - difference #Your answer
print(day2)
try this
from datetime import datetime
from datetime import timedelta
print(datetime.now() - timedelta(days=10))
i think you are looking for this. You can also pass day as datetime object
from datetime import datetime, timedelta
def get_start_end_day(day, delta):
if isinstance(day, str):
day = datetime.strptime(day, '%Y/%m/%d')
return day - timedelta(days=delta), day + timedelta(days=delta)
days = get_start_end_day('2021/09/09', 10)
print(days)
output
(datetime.datetime(2021, 8, 30, 0, 0), datetime.datetime(2021, 9, 19, 0, 0))
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.
I am hoping someone can point me in the right direction in working with dates and timedelta.
my understanding is that to add any number (ex: 10 days) to a date, you need to convert it to a timedelta.
if that is correct, how can I add any number to a date when it is an integer?
any documentation or links would be great - thank you.
code example, my date is as follows:
x = 20100103 (formatted as YYYYMMDD)
>>> import datetime
>>> today = datetime.datetime.now().date()
>>> today
datetime.date(2016, 6, 14)
>>> today + datetime.timedelta(days=10)
datetime.date(2016, 6, 24)
There's no need to convert it to a timedelta. Just use the timedelta function, if you want to add days, use days=N, for hours, timedelta(hours=20)
x=20100103
x2 = int((datetime.datetime.strptime(str(x),"%Y%m%d") + datetime.timedelta(days=10)).strftime("%Y%m%d"))
to break it down
x=20100103
x_as_datetime = datetime.datetime.strptime(str(x),"%Y%m%d")
new_datetime = x_as_datetime + datetime.timedelta(days=10) #add your timedelta
x2 = new_datetime.strftime("%Y%m%d") # format it back how you want
int(x2) # if you just want an integer ...
from datetime import datetime
from datetime import timedelta
StartDate = "20100103"
Date = datetime.strptime(StartDate, "%Y%m%d")
EndDate = Date + timedelta(days=10)
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)
Situation:
I am trying to construct a simple method that accepts two different integers that represent two different dates. 20120525 for May 25, 2012 and 20120627 for June 26, 2012 as an example. I want this method to return a list of these integer types that represent all days between the two date parameters.
Question:
Could I get any suggestions on how to do this and how to handle months of either 28, 29, 30 or 31 days in each. I think I can do this by extracting the numbers as integers through division/modding of powers of 10, and then incrementing these numbers as such with the particular conditions above, but I feel like there must be an easier way to do this.
You don't have to reinvent the wheel. Just parse the strings into datetime objects and let python do the math for you:
from dateutil import rrule
from datetime import datetime
a = '20120525'
b = '20120627'
for dt in rrule.rrule(rrule.DAILY,
dtstart=datetime.strptime(a, '%Y%m%d'),
until=datetime.strptime(b, '%Y%m%d')):
print dt.strftime('%Y%m%d')
prints
20120525
20120526
20120527
…
20120625
20120626
20120627
An alternative solution without using rrule goes here:
import datetime
d1 = datetime.date(2015, 1, 1)
d2 = datetime.date(2015, 2, 6)
days = [d1 + datetime.timedelta(days=x) for x in range((d2-d1).days + 1)]
for day in days:
print(day.strftime('%Y%m%d'))
Output:
20150101
20150102
20150103
<snip>
20150205
20150206
You can use pandas.date_range,
import pandas
pd.date_range('2012-05-25', '2012-06-27', freq='D')
which would produce,
DatetimeIndex(['2012-05-25', '2012-05-26', '2012-05-27', '2012-05-28',
'2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01',
...
'2012-06-22', '2012-06-23', '2012-06-24', '2012-06-25',
'2012-06-26', '2012-06-27'],
dtype='datetime64[ns]', freq='D')