Python Time Arithmetic - removing 3 hours from a python datetime object - python

I was working on a pandas plot and needed to start the plot from 3 hours earlier than the current time in order to remove the superfluous data prior to 3 hours ago.
I ended up doing it like this:
import datetime
todaydate = datetime.datetime.now() # sets todaydate to the current date and time`
tdiff = datetime.timedelta(hours=-3) # sets a time delay object to -3 hours
plotfrom = todaydate + tdiff # adds the datetime object to the timedelta object.
print (plotfrom.strftime("%Y-%m-%d %H:%M:%S") + " is three hours earlier than " + todaydate.strftime("%Y-%m-%d %H:%M:%S") )
>>> 2021-07-09 12:58:46 is three hours earlier than 2021-07-09 15:58:46
My question is is there a "one-liner" way of doing the same thing without using the diff variable?

It can is simple:
plotform = datetime.datetime.now() - datetime.timedelta(hours=-3)

from datetime import datetime, timedelta
plotfrom = datetime.now() - timedelta(hours=3)
plotfrom.strftime("%Y-%m-%d %H:%M:%S")

Use f-strings:
import datetime
todaydate = datetime.datetime.now()
>>> print(f"{(todaydate-datetime.timedelta(hours=3)).strftime('%Y-%m-%d %H:%M:%S')} is three hours earlier than {todaydate.strftime('%Y-%m-%d %H:%M:%S')}")
2021-07-09 08:16:23 is three hours earlier than 2021-07-09 11:16:23

For stuff like this I like arrow since the syntax is really easy to remember.
todaydate = arrow.now()
plotform = todaydate.shift(hours=-3)
print(plotfrom.format("YYYY-MM-DD HH:mm:ss") + " is three hours earlier than " + todaydate.format("YYYY-MM-DD HH:mm:ss"))
To get the raw datetime object from that, it's just plotform.datetime.

You can do math to datetimes inline.
import datetime
now_minus_three_hours = (datetime.datetime.now() - datetime.timedelta(hours=3)).strftime("%Y-%m-%d %H:%M:%S")
print("Three hours ago from local time is:", now_minus_three_hours)
Three hours ago from local time is: 2021-07-09 07:18:16

Related

Calculate and substract specific time for a date that is not today

I'm trying to code an auto-shutdown for my pc. I'm fairly new to progamming, to this may be easy to solve.
I have 2 dates
import datetime
startup_date = datetime.datetime.now() #This is the datetime when I start up my pc
shutdown_date = startup_date + datetime.timedelta(days=1) #Tomorrow
So, I want to make that shutdown_date happens at the next day 3 AM. I figured how to obtain tomorrow's date, but I don't know how to make that calculation in order to always have the timer pointing at next day 3 AM. Somedays I startup my pc at 12 pm, other days at 2pm. So I need to automatically calculate the difference between the startup timedate and the desired shutdown time (next day at 3 AM).
I'm sure this is pretty easy to solve, but I can't see it.
Thank you!
You could:
get today's date
add a day to it
replace its hour to 3AM:
import datetime
startup_date = datetime.datetime.now()
shutdown_date = startup_date + datetime.timedelta(days=1)
shutdown_date = shutdown_date.replace(hour=3, minute=0, second=0, microsecond=0)
You can start with your shutdown_date but then only use the date components, and hardcode the time to 03:00. Then you can subtract that new datetime from your startup_date
>>> import datetime
>>> startup_date = datetime.datetime.now()
>>> shutdown_date = startup_date + datetime.timedelta(days=1)
>>> tomorrow_morning = datetime.datetime(shutdown_date.year, shutdown_date.month, shutdown_date.day, hour=3)
>>> tomorrow_morning - startup_date
datetime.timedelta(seconds=48730, microseconds=54057)
Combine it with a 3 am time:
shutdown_date = datetime.datetime.combine(shutdown_date, datetime.time(3, 0))

How do you setup simple timer between two times when the other time is the next day?

Python noob here
from datetime import datetime, time
now = datetime.now()
now_time = now.time()
if now_time >= time(10,30) and now_time <= time(13,30):
print "yes, within the interval"
I would like the timer to work between 10,30 AM today and 10 AM the next day. Changing time(13,30) to time(10,00) will not work, because I need to tell python 10,00 is the next day. I should use datetime function but don't know how. Any tips or examples appreciated.
The combine method on the datetime class will help you a lot, as will the timedelta class. Here's how you would use them:
from datetime import datetime, timedelta, date, time
today = date.today()
tomorrow = today + timedelta(days=1)
interval_start = datetime.combine(today, time(10,30))
interval_end = datetime.combine(tomorrow, time(10,00))
time_to_check = datetime.now() # Or any other datetime
if interval_start <= time_to_check <= interval_end:
print "Within the interval"
Notice how I did the comparison. Python lets you "nest" comparisons like that, which is usually more succinct than writing if start <= x and x <= end.
P.S. Read https://docs.python.org/2/library/datetime.html for more details about these classes.
Consider this:
from datetime import datetime, timedelta
now = datetime.now()
today_10 = now.replace(hour=10, minute=30)
tomorrow_10 = (now + timedelta(days=1)).replace(hour=10, minute=0)
if today_10 <= now <= tomorrow_10:
print "yes, within the interval"
The logic is to create 3 datetime objects: one for today 10 AM, one for right now and one for tomorrow 10 AM. Them simply checking for the condition.
An alternative to creating time objects for the sake of comparison is to simply query the hour and minute attributes:
now= datetime.now().time()
if now.hour<10 or now.hour>10 or (now.hour==10 and now.minute>30):
print('hooray')

To get date & time in python

How to get the current date with zero hours in python?
When i am trying datetime.datetime.now() it is showing current date & time but i would like to get current date with zero hours.
You can use strftime to format the time as follows, this will give you the 'time' without the hours, minutes etc:
timeFormat = "%Y-%m-%d"
time_now = time.strftime(time.time())
Alternatively, if you want todays date, without a time aspect, use this from datetime
from datetime import date
today = date.today().strftime("%Y-%m-%d_%H:%M")
You can try the following code if you don't want to show hours in your code:
print str(datetime.datetime.now().date()) + " "+str(datetime.datetime.now().minute) + ":" + str(datetime.datetime.now().second)

python subtract time and run if loop

I want to compare two times and if the new time is more than 2min then the if statement will print output, I can get the output of datetime.datetime.now() , but how do I check whether the old time is less than 2mins?
#!/usr/bin/env python
import datetime
from time import sleep
now = datetime.datetime.now()
sleep(2)
late = datetime.datetime.now()
constant = 2
diff = late-now
if diff <= constant:
print "True time is less than 2min"
else:
print "Time exceeds 2 mins"
any ideas?
UPDATED:
I am now storing the old date as string in file and then subtract it from current time, the old date is stored in the format
2011-12-16 16:14:50.800856
so when I do
now = "2011-12-16 16:14:50.838638"
sleep(2)
nnow = datetime.strptime(now, '%Y-%m-%d %H:%M:%S')
late = datetime.now()
diff = late-nnow
it gives me this error
ValueError: unconverted data remains: .838638
Subtracting two datetime instances returns a timedelta that has a total_seconds method:
contant = 2 * 60
diff = late-now
if diff.total_seconds() <= constant:
This is only an answer to the update since the answer from sje397 was perfect.
Use a format string like this to match the whole time string:
nnow = datetime.strptime(now, '%Y-%m-%d %H:%M:%S.%f')
The %f matches the microseconds after the dot. This is new since Python 2.6.
You could compare datetime objects by themselves:
from datetime import datetime, timedelta
ts = datetime.strptime("2011-12-16 16:14:50.838638Z", '%Y-%m-%d %H:%M:%S.%fZ')
ts += timedelta(minutes=2) # add 2 minutes
if datetime.utcnow() < ts:
print("time is less")
else:
print("time is more or equal")

How to calculate the time interval between two time strings

I have two times, a start and a stop time, in the format of 10:33:26 (HH:MM:SS). I need the difference between the two times. I've been looking through documentation for Python and searching online and I would imagine it would have something to do with the datetime and/or time modules. I can't get it to work properly and keep finding only how to do this when a date is involved.
Ultimately, I need to calculate the averages of multiple time durations. I got the time differences to work and I'm storing them in a list. I now need to calculate the average. I'm using regular expressions to parse out the original times and then doing the differences.
For the averaging, should I convert to seconds and then average?
Yes, definitely datetime is what you need here. Specifically, the datetime.strptime() method, which parses a string into a datetime object.
from datetime import datetime
s1 = '10:33:26'
s2 = '11:15:49' # for example
FMT = '%H:%M:%S'
tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT)
That gets you a timedelta object that contains the difference between the two times. You can do whatever you want with that, e.g. converting it to seconds or adding it to another datetime.
This will return a negative result if the end time is earlier than the start time, for example s1 = 12:00:00 and s2 = 05:00:00. If you want the code to assume the interval crosses midnight in this case (i.e. it should assume the end time is never earlier than the start time), you can add the following lines to the above code:
if tdelta.days < 0:
tdelta = timedelta(
days=0,
seconds=tdelta.seconds,
microseconds=tdelta.microseconds
)
(of course you need to include from datetime import timedelta somewhere). Thanks to J.F. Sebastian for pointing out this use case.
Try this -- it's efficient for timing short-term events. If something takes more than an hour, then the final display probably will want some friendly formatting.
import time
start = time.time()
time.sleep(10) # or do something more productive
done = time.time()
elapsed = done - start
print(elapsed)
The time difference is returned as the number of elapsed seconds.
Here's a solution that supports finding the difference even if the end time is less than the start time (over midnight interval) such as 23:55:00-00:25:00 (a half an hour duration):
#!/usr/bin/env python
from datetime import datetime, time as datetime_time, timedelta
def time_diff(start, end):
if isinstance(start, datetime_time): # convert to datetime
assert isinstance(end, datetime_time)
start, end = [datetime.combine(datetime.min, t) for t in [start, end]]
if start <= end: # e.g., 10:33:26-11:15:49
return end - start
else: # end < start e.g., 23:55:00-00:25:00
end += timedelta(1) # +day
assert end > start
return end - start
for time_range in ['10:33:26-11:15:49', '23:55:00-00:25:00']:
s, e = [datetime.strptime(t, '%H:%M:%S') for t in time_range.split('-')]
print(time_diff(s, e))
assert time_diff(s, e) == time_diff(s.time(), e.time())
Output
0:42:23
0:30:00
time_diff() returns a timedelta object that you can pass (as a part of the sequence) to a mean() function directly e.g.:
#!/usr/bin/env python
from datetime import timedelta
def mean(data, start=timedelta(0)):
"""Find arithmetic average."""
return sum(data, start) / len(data)
data = [timedelta(minutes=42, seconds=23), # 0:42:23
timedelta(minutes=30)] # 0:30:00
print(repr(mean(data)))
# -> datetime.timedelta(0, 2171, 500000) # days, seconds, microseconds
The mean() result is also timedelta() object that you can convert to seconds (td.total_seconds() method (since Python 2.7)), hours (td / timedelta(hours=1) (Python 3)), etc.
This site says to try:
import datetime as dt
start="09:35:23"
end="10:23:00"
start_dt = dt.datetime.strptime(start, '%H:%M:%S')
end_dt = dt.datetime.strptime(end, '%H:%M:%S')
diff = (end_dt - start_dt)
diff.seconds/60
This forum uses time.mktime()
Structure that represent time difference in Python is called timedelta. If you have start_time and end_time as datetime types you can calculate the difference using - operator like:
diff = end_time - start_time
you should do this before converting to particualr string format (eg. before start_time.strftime(...)). In case you have already string representation you need to convert it back to time/datetime by using strptime method.
I like how this guy does it — https://amalgjose.com/2015/02/19/python-code-for-calculating-the-difference-between-two-time-stamps.
Not sure if it has some cons.
But looks neat for me :)
from datetime import datetime
from dateutil.relativedelta import relativedelta
t_a = datetime.now()
t_b = datetime.now()
def diff(t_a, t_b):
t_diff = relativedelta(t_b, t_a) # later/end time comes first!
return '{h}h {m}m {s}s'.format(h=t_diff.hours, m=t_diff.minutes, s=t_diff.seconds)
Regarding to the question you still need to use datetime.strptime() as others said earlier.
Try this
import datetime
import time
start_time = datetime.datetime.now().time().strftime('%H:%M:%S')
time.sleep(5)
end_time = datetime.datetime.now().time().strftime('%H:%M:%S')
total_time=(datetime.datetime.strptime(end_time,'%H:%M:%S') - datetime.datetime.strptime(start_time,'%H:%M:%S'))
print total_time
OUTPUT :
0:00:05
import datetime as dt
from dateutil.relativedelta import relativedelta
start = "09:35:23"
end = "10:23:00"
start_dt = dt.datetime.strptime(start, "%H:%M:%S")
end_dt = dt.datetime.strptime(end, "%H:%M:%S")
timedelta_obj = relativedelta(start_dt, end_dt)
print(
timedelta_obj.years,
timedelta_obj.months,
timedelta_obj.days,
timedelta_obj.hours,
timedelta_obj.minutes,
timedelta_obj.seconds,
)
result:
0 0 0 0 -47 -37
Both time and datetime have a date component.
Normally if you are just dealing with the time part you'd supply a default date. If you are just interested in the difference and know that both times are on the same day then construct a datetime for each with the day set to today and subtract the start from the stop time to get the interval (timedelta).
Take a look at the datetime module and the timedelta objects. You should end up constructing a datetime object for the start and stop times, and when you subtract them, you get a timedelta.
you can use pendulum:
import pendulum
t1 = pendulum.parse("10:33:26")
t2 = pendulum.parse("10:43:36")
period = t2 - t1
print(period.seconds)
would output:
610
import datetime
day = int(input("day[1,2,3,..31]: "))
month = int(input("Month[1,2,3,...12]: "))
year = int(input("year[0~2020]: "))
start_date = datetime.date(year, month, day)
day = int(input("day[1,2,3,..31]: "))
month = int(input("Month[1,2,3,...12]: "))
year = int(input("year[0~2020]: "))
end_date = datetime.date(year, month, day)
time_difference = end_date - start_date
age = time_difference.days
print("Total days: " + str(age))
Concise if you are just interested in the time elapsed that is under 24 hours. You can format the output as needed in the return statement :
import datetime
def elapsed_interval(start,end):
elapsed = end - start
min,secs=divmod(elapsed.days * 86400 + elapsed.seconds, 60)
hour, minutes = divmod(min, 60)
return '%.2d:%.2d:%.2d' % (hour,minutes,secs)
if __name__ == '__main__':
time_start=datetime.datetime.now()
""" do your process """
time_end=datetime.datetime.now()
total_time=elapsed_interval(time_start,time_end)
Usually, you have more than one case to deal with and perhaps have it in a pd.DataFrame(data) format. Then:
import pandas as pd
df['duration'] = pd.to_datetime(df['stop time']) - pd.to_datetime(df['start time'])
gives you the time difference without any manual conversion.
Taken from Convert DataFrame column type from string to datetime.
If you are lazy and do not mind the overhead of pandas, then you could do this even for just one entry.
Here is the code if the string contains days also [-1 day 32:43:02]:
print(
(int(time.replace('-', '').split(' ')[0]) * 24) * 60
+ (int(time.split(' ')[-1].split(':')[0]) * 60)
+ int(time.split(' ')[-1].split(':')[1])
)

Categories