How do I print the time every 10 seconds based off of using the % operator and the datetime package? This only prints once...
from datetime import datetime, timezone, timedelta
import time
now_utc = datetime.now(timezone.utc)
while True:
if (now_utc - datetime.now(timezone.utc)).total_seconds() % 10 == 0:
print(time.ctime())
In response to comments on the question: you can do this without datetime and %. The benefit is that it's much simpler.
import time
POLLING_PERIOD = 0.1 # seconds
if __name__ == '__main__':
prev_time = time.time()
print(time.ctime())
while True:
cur_time = time.time()
if cur_time - prev_time >= 10:
prev_time = cur_time
print(time.ctime())
time.sleep(POLLING_PERIOD)
This script gets the seconds from Unix epoch and prints the current time every 10s. You can adjust the polling period to minimize spinning and ensure that the time is printed only every 10s, rather than 11s, 12s, etc. due to poor resolution.
Please note that this script is susceptible to drift due to inaccuracy of time.sleep() and will eventually print a time which is greater than 10s since the last printed time.
After running some experiments on a system with low load, time.sleep() performs very well over several hours if the sleep time is adjusted based on the difference between the previous and current times.
import time
REPORTING_INTERVAL = 10 # seconds
if __name__ == '__main__':
prev_time = time.time()
sleep_time_adj = 0
print(time.ctime())
while True:
time.sleep(REPORTING_INTERVAL - sleep_time_adj)
print(time.ctime())
cur_time = time.time()
sleep_time_adj = cur_time - prev_time - REPORTING_INTERVAL
prev_time = cur_time
It really comes down to how accurate this needs to be, how long it's going to run, and the system it will run on.
Related
I am trying to delay commands with a delta from the initial time of execution. In other words, I want a start time point that the rest of the commands are delayed in reference to that start time point. Example:
print("start")
# command that delays for a minute since the start
print("it's been a 1 min")
# command that delays for n minute since the start
print("it's been n min")
I am trying to switch from sleep(), but haven't found something that fits what I need. Any assistance is appreciated.
import time
initial_time = int(time.time()) #frame of reference in seconds
def delta_sleep(s):
"""
Parameters:
s: seconds since elapsed to sleep until
"""
if int(time.time()) > initial_time + s:
# check if the delta time has already passed
return
else:
# find time needed to sleep to reach the specified param 's'
needed_sleep = (initial_time+s) - int(time.time())
time.sleep(needed_sleep)
# example
print("The program has started")
delta_sleep(5)
print("Five seconds have passed")
delta_sleep(8)
print("8 seconds have passed")
delta_sleep(1) # does not sleep at all
I need code that will do this:
def foo():
now = datetime.datetime.utcnow()
# Some code will run that takes a variable amount of time
# (less than 15 minutes)
# This code should run no sooner than 15 minutes after `now`
Note that this is not the same as using time.sleep! time.sleep would halt the entire process, but I need computation in foo() to happen and for foo() to return no sooner than 15 minutes after it begins.
You need to calculate the time between the current time and the desired restart time. Then sleep for that amount of time.
wait_time = 15 # minutes
restart_time = datetime.datetime.now() + datetime.timedelta(minutes=wait_time)
# execute code that takes a long time
# for example, let's just sleep for some time
random_time = random.randint(1, wait_time)
time.sleep(random_time * 60)
print("See you again at ", restart_time)
# Now, calculate how long you need to sleep to resume at restart_time
sleep_time = restart_time - datetime.datetime.now()
# Sleep for that amount of time
time.sleep(sleep_time.total_seconds())
print("Hi, I'm back ", datetime.datetime.now())
datetime is not needed, because we do not need to think in human clock terms (hours, minutes, seconds).
All we need is a number of seconds since any fixed moment in the past and time.monotonic does exactly that.
import time
DELAY = 900 # in seconds
start = time.monotonic()
# computation here
end = time.monotonic()
duration = end - start
time.sleep(DELAY - duration)
Last three lines can be written as time.sleep(start + DELAY - time.monotonic()), I split it for simplicity.
import time
import random
import datetime
wait = random.randint(1, 14)
now = datetime.datetime.utcnow()
print(now)
time.sleep(wait * 60)
now = datetime.datetime.utcnow()
print(now)
I think this solves it.
I am trying to time a running function. But I need to know how many hours/minutes/seconds does it takes. I am using time.time(), but I don't understand the output. How can I convert this output in terms of how many hours/minutes/seconds does a function took? Or, if there is another proper library?
import time
starttime = time.time()
x=0
for i in range(100000):
x+=i
endtime = time.time()
print('Job took: ', endtime-starttime)
I'd recommend using time.perf_counter instead of time.time, and using timedelta to format the units:
>>> from datetime import timedelta
>>> import time
>>> starttime = time.perf_counter()
>>> x=0
>>> for i in range(100000):
... x+=i
...
>>> duration = timedelta(seconds=time.perf_counter()-starttime)
>>> print('Job took: ', duration)
Job took: 0:00:00.015017
The benefit of using perf_counter is that it won't be impacted by weird things like the timezone or system clock changing while you're measuring, and its resolution is guaranteed to be as high as possible (which may be important if you're timing very quick events).
In either case, the return value is measured in seconds, but you need to know what function it came from in order to know what the float value corresponds to. timedelta is a nicer way to represent a duration than a pure float IMO because it includes the units.
time.time():
The time() function returns the number of seconds passed since epoch.
For Unix system, January 1, 1970, 00:00:00 at UTC is epoch (the point
where time begins).
import time
seconds = time.time()
print("Seconds since epoch =", seconds)
This might not be what you want
time.time() gives the seconds when you started a process. Therefore endtime-starttime gives you the amount of seconds between the beginning and the end of the loop.
A preferable way to stop time in python is to use datetime:
import datetime
starttime = datetime.datetime.now()
x=0
for i in range(100000):
x+=i
endtime = datetime.datetime.now()
diff = endtime - starttime
print('Job took: ', diff.days, diff.seconds, diff.microseconds)
I'm creating a loop which executes every 5 seconds, starting at the startTime variable and ending at the stopTime variable. However, the code below is disregarding the minutes within my startTime and endTime variables and only executing on the hour. For example, even though my startTime is '1130', the code is executing 11:05, rather than ending the loop. I have the same problem with the endTime variable. If the current time is 12:45, the code still executes even though the endTime variable is '1230'. The code will stop executing at '1300'.
frequency = 5
startTime = '1130'
endTime = '1230'
while True:
now = datetime.now().strftime('%H:%M:%S')
if startTime <= now <= endTime:
print('Loop is working. Time is: ',now)
time.sleep(frequency)
else:
print('Loop is stopped')
break
I live in Central Time, so I tried switching to Eastern timezone by modifying the "now" variable to:
now = datetime.now(timezone('US/Eastern')).strftime('%H:%M:%S.%f %Z')
but I still get the same problem when I substitute eastern times with startTime and endTime when using the eastern datetime.now().
Is executing code at a precise minute possible with strftime()?
EDIT: (this is now the answer to the real question (oops))
If you want to wait till for example 11:30 (which was the real question)
you can calculate the time (in seconds) the program should sleep (and let it sleep for that time):
def wait_till(hour, minute, second=0):
# get system time (and date)
now_time = datetime.datetime.now()
# create time point we are waiting for (this year, this month and this day)
wait_till_time = datetime.datetime(year=now_time.year, month=now_time.month, day=now_time.day, hour=hour, minute=minute, second=second)
# calculate time we want to wait for and convert to seconds
wait_for = (wait_till_time - now_time).total_seconds()
# check if it's going to be tomorrow (if we would sleep for a negative amount of seconds)
if wait_for < 0:
# add one day
wait_till_time = wait_till_time.replace(day=now_time.day+1)
# recalculate (not very beautiful, but i don't know a better way)
wait_for = (wait_till_time - now_time).total_seconds()
# printing this waiting time (in seconds)
print("waiting for",wait_for,"seconds")
# sleeping for that time
time.sleep(wait_for)
# printing the new now time, so we can see how accurate it is
print("its now",datetime.datetime.now())
and say for example:
wait_till(20, 24) # waiting till 20:24 (today)
and get:
waiting for 15.32297 seconds
its now 2019-03-11 20:24:00.003857
which is pretty darn close to what we wanted (20:24:00.000000) and this delay is probably only caused by the calculation lag of formatting the string.
(The old stuff ...)
if it's not important that it takes 100% 5s (but rather 100.04546642303467% --> it will get off a little bit every time) you can just do
import time
frequency = 5 #every 5 seconds
start_time = time.time()
while 1:
elspsed_time = time.time() - start_time
print(elspsed_time)
time.sleep(frequency)
but if you need the 100% you can try this autocorrecting solution:
import time
from threading import Timer
frequency = 5 #every 5 seconds
start_time = time.time()
def what_to_do_after_5s():
elapsed_time = time.time() - start_time
print(elapsed_time)
# next call
Timer(5.0 - (elapsed_time - int(elapsed_time)), what_to_do_after_5s, ()).start()
what_to_do_after_5s()
and we can see that it autocorrects:
0.0
5.000170707702637
10.000272989273071
15.000539064407349
20.001248836517334
25.00046443939209
30.000929355621338
35.00142860412598
40.0007688999176
45.00128436088562
50.00045442581177
55.000683069229126
60.00123882293701
65.00095415115356
70.0015127658844
i have this script but counts from seconds while the scripts ends in less than a second.
import time
start = time.time()
p=[1,2,3,4,5]
print('It took {0:0.1f} seconds'.format(time.time() - start))
python 3.7 uses a new function that can do that. I have 3.6.5. How do i do that?
time.perf_counter(), available since Python 3.3, lets you access a high-resolution wallclock.
t0 = time.perf_counter()
time.sleep(.1)
print(time.perf_counter() - t0)
It doesn't count in seconds. It counts in fractions of a second, it's just that the script ends faster than the precision allowed by the string formatted float, ie. much less than a second.
Try:
import time
start = time.time()
p=[1,2,3,4,5]
time.sleep(0.5)
print('It took {0:0.1f} seconds'.format(time.time() - start))
Also, for shorter sleep you may want to increase the precision of your float formatter (eg {0:0.3f}), so that for shorter sleeps (eg 0.007) you don't have a 0.0 printed to console.
import time
start = time.time()
p=[1,2,3,4,5]
time.sleep(0.007)
print('It took {0:0.3f} seconds'.format(time.time() - start))
Or just remove the formatter entirely (As commented by Inder):
import time
start = time.time()
p=[1,2,3,4,5]
time.sleep(0.007)
print ('It took ' + str(time.time()-start) + ' seconds')
See here for more details of timer resolution: https://docs.python.org/2/library/time.html