This question already has answers here:
What's the best way to find the inverse of datetime.isocalendar()?
(8 answers)
Closed 8 years ago.
I'm writing a script where the user needs to input a week number and a procedure will be ran based on that. However, I ran into a small issue, I know I can get week numbers via something like this:
>>> a=datetime.datetime.now()
>>> a
datetime.datetime(2015, 1, 22, 15, 51, 57, 820058)
>>> a.isocalendar()[1]
4
But I can't find how to do it backwards. Also, the date I require has to be Sunday of that week at 6:00am. Once I have that datetime element I can just do
begin_date = datetime.datetime.strptime(a, "%Y-%m-%d %H:%M:%S")
To get the format I want. I'm still missing the step to get the date. Any thoughts?
We create an initial datetime of for 2015 (2014-12-28 6:00:00 --1st sunday of 1st week), and a timedelta object of 7 days:
w0 = datetime.datetime(2014,12,28,6)
d7 = datetime.timedelta(7)
Then you can simply add multiples of the timedelta object to the initial date like so (n would be your week number):
w0+(d7*n)
>>> now = datetime.datetime.now()
>>> start = datetime.datetime(2015, 1,1)
>>> (now - start).days // 7
3
Related
I've seen about 30 similar posts to this, but nothing really doing exactly what I'm looking for and some which just don't work..
I'm trying to return a list of N business dates, to then iterate through a dictionary and pull data out according to the corresponding dates.
Assuming the current date is:
refreshed = str(data['Meta Data']['3. Last Refreshed'])
For completion, the value of above right now is:2020-1-30
I want to be able to calculate n days prior to this date..
I don't really want to import a bunch of funky modules, and have tried a function using a loop and datetime.date.isoweekday() - but I always come across an issue when passing refreshed in.
One of the main issues I'm seeing with some of the examples elsewhere is where the examples are calculating the dates from datetime.date.today() - seemingly it's fine to pass that to isoweekday() but I can't pass refreshed to isoweekday() to calculate it's 0-6 reference. I've tried using strfrtime() to reformat the date into a suitable format for isoweekday but to no avail.
Subtracting days from a date
You can subtract 30 days from a datetime.datetime object by subtracting a datetime.timedelta object:
>>> import datetime
>>> datetime.datetime.today()
datetime.datetime(2020, 10, 31, 10, 20, 0, 704133)
>>> datetime.datetime.today() - datetime.timedelta(30)
datetime.datetime(2020, 10, 1, 10, 19, 49, 680385)
>>> datetime.datetime.strptime('2020-01-30', '%Y-%m-%d') - datetime.timedelta(30)
datetime.datetime(2019, 12, 31, 0, 0)
Skipping week-ends by subtracting 7 days instead of 5
We are starting from date d and you want to subtract N=30 non-week-end days. A general way could be:
Figure out which day of the week is d;
Figure out how many week-ends there are between d and d-N;
Remove the appropriate number of days.
However, you want to subtract 30 days, and 30 is a multiple of 5. This makes things particularly easy: when you subtract 5 days from a date, you are guaranteed to encounter exactly one week-end in those five days. So you can immediately remove 7 days instead of 5.
Removing 30 days is the same as removing 6 times 5 days. So you can remove 6 times 7 days instead, which is achieved by subtracting datetime.timedelta(42) from your date.
Note: this accounts for week-ends, but not for special holidays.
Skipping week-ends iteratively
You can test for days of the week using .weekday(). This is already answered on this other question: Loop through dates except for week-ends
You can add N days using a timedelta:
data['Meta Data']['3. Last Refreshed'] = pd.to_datetime(data['Meta Data']['3. Last Refreshed']) + pd.to_timedelta(4, unit="D")
Replace 4 with your n days.
This question already has answers here:
Days between two dates? [duplicate]
(4 answers)
Closed 5 years ago.
I need to design a code that will automatically generate the date X number of days from current date.
For that, I currently have a function that returns an epoch timestamp, which I then add the fixed number of days in seconds. However, I am currently stuck there and do not know how to convert the epoch timestamp into a Gregorian calendar date format (DD/MM/YYYY HH:MM). Displaying time is optional, can be rounded to the nearest day.
A way to do this without using an epoch timestamp and directly getting the current date in a readable format, printing it, and adding X days to it before generating the second date, is also fine, but I have no idea how that would work.
Any help/input would be much appreciated. Thanks in advance.
You can use timedelta.
import datetime as dt
x = 5 # Days offset.
now = dt.datetime.now()
>>> now + dt.timedelta(days=x)
datetime.datetime(2017, 12, 2, 21, 10, 19, 290884)
Or just using days:
today = dt.date.today()
>>> today + dt.timedelta(days=x)
datetime.date(2017, 12, 2)
Easy enough to convert back to a string using strftime:
>>> (today + dt.timedelta(days=x)).strftime('%Y-%m-%d')
'2017-12-02'
import datetime
x = 5
'''
Date_Time = datetime.datetime.now()#It wil give Date & time both
Time = datetime.datetime.now().time()#It will give Time Only
'''
Date = datetime.datetime.now().date()#It will give date only
print(Date + datetime.timedelta(days=x))#It will add days to current date
Output:
2017-12-03
so I am a beginner with python and have been working with the datetime, time, and timedelta libraries a little bit. I am trying to create a piece of code that gives me the date approximately two months ago(exact_two_months_date) from today (whatever today happens to be). The catch is, I want to find that date approx. two months ago AND begin the actual start_date on the Monday of that week. So in theory, the actual start date will not be exactly two months ago. It will be the week beginning on Monday two months ago from today.
Example pseudocode:
today = '20150425' ## '%Y%m%d' ... Saturday
exact_two_months_date = '20150225' ## EXACTLY two months ago ... Wednesday
start_date = '20150223' ## this is the Monday of that week two months ago
So how do I find the 'start_date' above? If the day exactly two months ago begins on a Saturday or Sunday, then I would just want to go to the next Monday. Hope this is clear and makes sense... Once I find the start date, I would like to increment day by day(only week days) up to 'today'.
Appreciate any feedback, thanks.
Calculating with dates using python-dateutil
If a dependency on a third-party package is an option, then ☞ python-dateutil provides a convenient method to calculate with dates.
Browse the docs for ☞ relativedelta to see the wealth of supported parameters. The more calculations a package needs to do with dates, the more a helper module like dateutil justifies its dependency. For more inspiration on what it has to offer see the ☞ examples page.
Quick run-through:
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.date.today()
>>> two_m_ago = today - relativedelta(months=2)
>>> # print two_m_ago ~> datetime.date(2015, 2, 25)
>>> monday = two_m_ago - datetime.timedelta(days=two_m_ago.weekday())
>>> # print monday ~> datetime.date(2015, 2, 23)
Getting the Monday with weekday()
Once we have the date from two months ago in the variable two_m_ago, we subtract the index of the weekday() from it. This index is 0 for Monday and goes all the way to 6 for Sunday. If two_m_ago already is a Monday, then subtracting by 0 will not cause any changes.
Does something like this work for you?
import datetime
today = datetime.date.today()
delta = datetime.timedelta(days=60) # ~ 2 months
thatDay = today - delta
# subtract weekdays to get monday
thatMonday = thatDay - datetime.timedelta(days=thatDay.weekday())
Honestly, I find working with datetimes to be the hardest thing I ever have to regularly do and I make a lot of mistakes, so I'm going to work through this one and show some of the failures I regularly have with it. Here goes.
Two constraints: 1) Date two months ago, 2) Monday of that week
Date Two Months Ago
Okay, so Python's datetime library has a useful method called replace, which seems like it might help here:
>>> import datetime
>>> now = datetime.date.today()
>>> today
datetime.date(2015, 4, 25)
>>> today.month
4
>>> two_months_ago = today.replace(month=today.month-2)
>>> two_months_ago
datetime.date(2015, 2, 25)
>>> two_months_ago.month
2
But wait: what about negative numbers? That won't work:
>>> older = datetime.date(2015, 01, 01)
>>> older.replace(month=older.month-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: month must be in 1..12
So there are two solutions:
1) I can build a 1-12 range that cycles forwards or back, or
2) To find two months previous, I can merely replace the day part of my date with the 1st day of the month I'm in and then go back 1 day to the previous month and then replace that day in the previous month with the day I want.
(If you think about it, you'll find that either of these may present bugs if I land on day 31 in a month with fewer days than that, for instance. This is part of what makes datetimes difficult.)
def previous_month(date):
current_day = date.day
first_day = date.replace(day=1)
last_day_prev_month = first_day - datetime.timedelta(days=1)
prev_month_day = last_day_prev_month.replace(day=current_day)
return prev_month_day
>>> today = datetime.date.today()
>>> older = previous_month(today)
>>> older
datetime.date(2015, 3, 25)
Well, let's say we're getting close, though, and we need to include some error-checking to make sure the day we want is a valid date inside the month we land in. Ultimately, the problem is that "two months ago" means a lot more than we think it means when we say it out loud.
Next, we'll take a crack at problem number two: How to get to the Monday of that week?
Well, datetime objects have a weekday method, so this part shouldn't be too hard and here's a nice SO answer on how to do that.
Simple version is: use the difference in weekday integers to figure out how many days to go back and do that using datetime.timedelta(days=days_difference).
Takeaway: Working with datetimes can be tough.
Date manipulation in Python is horribly convoluted. You will save a lot of time by using the arrow package which greatly simplifies these operations.
First install it
pip install arrow
Now your question:
import arrow
# get local current time
now = arrow.now('local')
# move 2 months back
old = now.replace(months=-2)
# what day of the week was that?
dow = old.isoweekday()
# reset old to Monday, for instance at 9:32 in the morning (this is just an example, just to show case)
old = old.replace(days=-dow, hour=9, minute=32, second=0)
print('now is {now}, we went back to {old}'.format(now=now.isoformat(), old=old.isoformat()))
The output:
now is 2015-04-25T20:37:38.174000+02:00, we went back to 2015-02-22T09:32:00.174000+01:00
Note that the various formats, timezones etc. are now transparent and you just need to rely on one package.
This question already has answers here:
How to calculate number of days between two given dates
(15 answers)
Closed 8 years ago.
I'm having trouble doing this in a clean and simple way in python.
What I'd like to do is having a piece of code that calculates the number of days passed between 2 dates.
For example today being the 22nd of december and i want to know how many days i have before the 15th of febuary. There are 55 days difference
(i took this example because it englobes 2 different years an multiple months)
What i made was very messy and dosen't work half the time so i'm kind of embarrassed to show it.
Any help is appreciated.
Thanks in advance
Simpler implementation:
import datetime
d1 = datetime.datetime(2013,12,22)
d2 = datetime.datetime(2014,2,15)
(d2-d1).days
just create an instance of both the dates and substract them - you'll get timedelta object with a given info.
>>> from datetime import date
>>> by = date(2013, 12, 22)
>>> since = date(2014, 2, 15)
>>> res = since - by
>>> res.days
55
some examples with a variables
>>> variables_tuple = (2013, 12, 22)
>>> by = date(*variables_tuple)
>>> by.year
2013
>>> until_year = 2014
>>> until = date(until_year, 2, 15)
I am using the datetime Python module in django. I am looking to calculate the date if the expiry date is less than or equal to 6 months from the current date.
The reason I want to generate a date 6 months from the current date is to set an alert that will highlight the field/column in which that event occurs. I dont know if my question is clear. I have been reading about timedelta function but cant really get my head round it. I am trying to write an if statement to statisfy this condition. Anyone able to help me please? Am a newbie to django and python.
There are two approaches, one only slightly inaccurate, one inaccurate in a different way:
Add a datetime.timedelta() of 365.25 / 2 days (average year length divided by two):
import datetime
sixmonths = datetime.datetime.now() + datetime.timedelta(days=365.25/2)
This method will give you a datetime stamp 6 months into the future, where we define 6 monhs as exactly half a year (on average).
Use the external dateutil library, it has a excellent relativedelta class that will add 6 months based on calendar calculations to your current date:
import datetime
from dateutil.relativedelat import relativedelta
sixmonths = datetime.datetime.now() + relativedelta(months=6)
This method will give you a datetime stamp 6 months into the future, where the month component of the date has been forwarded by 6, and it'll take into account month boundaries, making sure not to cross them. August 30th plus 6 months becomes February 28th or 29th (leap years permitting), for example.
A demonstration could be helpful. In my timezone, at the time of posting, this translates to:
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2013, 2, 18, 12, 16, 0, 547567)
>>> now + datetime.timedelta(days=365.25/2)
datetime.datetime(2013, 8, 20, 3, 16, 0, 547567)
>>> now + relativedelta(months=6)
datetime.datetime(2013, 8, 18, 12, 16, 0, 547567)
So there is a 1 day and 15 hour difference between the two methods.
The same methods work fine with datetime.date objects too:
>>> today = datetime.date.today()
>>> today
datetime.date(2013, 2, 18)
>>> today + datetime.timedelta(days=365.25/2)
datetime.date(2013, 8, 19)
>>> today + relativedelta(months=6)
datetime.date(2013, 8, 18)
The half-year timedelta becomes a teensy less accurate when applied to dates only (the 5/8th day component of the delta is ignored now).
If by "6 months" you mean 180 days, you can use:
import datetime
d = datetime.date.today()
d + datetime.timedelta(6 * 30)
Alternatively if you, mean actual 6 months by calendar you'll have to lookup the calendar module and do some lookups on each month. For example:
import datetime
import calendar
def add_6_months(a_date):
month = a_date.month - 1 + 6
year = a_date.year + month / 12
month = month % 12 + 1
day = min(a_date.day,calendar.monthrange(year, month)[1])
return datetime.date(year, month, day)
I would give Delorean a look a serious look. It is built on top of dateutil and pytz to do what you asked would simply be the following.
>>> d = Delorean()
>>> d
Delorean(datetime=2013-02-21 06:00:21.195025+00:00, timezone=UTC)
>>> d.next_month(6)
Delorean(datetime=2013-08-21 06:00:21.195025+00:00, timezone=UTC)
It takes into account all the dateutil calculations as well as provide and interface for timezone shifts. to get the needed datetime simple .datetime on the Delorean object.
this might work for you in case you want to get an specfic date back:
from calendar import datetime
datetime.date(2019,1,1).strftime("%a %d")
#The arguments here are: year, month, day and the method is there to return a formated kind of date - in this case - day of the week and day of the month.
The outcome would be:
Tue 01
Hope it helps!