I want to get all the time between start time and end time in python, so I was using for loop with range function.
There are 2 variables, a and b which have time in %H:%M:%S format.
These 2 variables are start and end time and I want to print all the time between the start and end time.
import datetime
from datetime import datetime
import time
a = '20:15:16'
b = '20:32:55'
a = datetime.strptime(a,'%H:%M:%S').time()
b = datetime.strptime(b,'%H:%M:%S').time()
for i in range(a,b):
print(i)
For this I am getting an error - datetime.time' object cannot be interpreted as an integer.
I want to print all the time between a and b.
There are infinite moments between two times. I think you might be asking, "How can I print a timestamp for every second or every minute between A and B?"
I don't think you want to be using the range function. The error you are seeing is because range expects integers as input, not whole datetime objects.
Here is something that may do what you want:
from datetime import datetime, timedelta
# Define our times
str_A = '20:15:16'
str_B = '20:32:55'
# Create our datetime objects
A = datetime.strptime(str_A,'%H:%M:%S')
B = datetime.strptime(str_B,'%H:%M:%S')
# Create a loop where you print a time, starting with time A
# and then increase the time stamp by some value, in this case,
# 1 minute, until you reach time B
tmp = a
while tmp <= b:
print(tmp.time())
tmp = tmp + timedelta(minutes=1)
Please notice the line,
print(tmp.time())
where we only extract the time part when we need it, leaving the object as a datetime object for easy manipulation.
I used this question for reference:
What is the standard way to add N seconds to datetime.time in Python?
So this question is really adorable. There is something about reading, 'I need to print "all the time" between these two times' that gives me joy.
I have a string that looks like this
time = "2020-04-15 21:27"
That's based on normal time zone +0
how can i add hours to the string so it become like this
for example let's add 5 hours to the time
the time string will become like this
time = "2020-04-15 02:27"
then the day should be updated
so the final result will look like this
time = "2020-04-15 02:27"
how can i do that ?
Edit:
i also need to change the day because 24 hours have passed
It is unclear if you mean creating your own clock or just updating a string every hour.
Option one:
import time
While True:
t = time.ctime(%h)
print(t)
#the above produces a live clock only showing hours.
#you could add %s for seconds separated by commas and thd like.
Option 2:
import time
T = #whatever you want it to be
time.sleep(300)
T = the prev num bit you want to change + 5
Hope this helps!
Happy coding
I'm a pretty new python user, working on a project that will be used by people who won't really understand how picky python can be about inputs. For the program, I need to get user input telling me how long a video is(minutes and seconds), and then I need to subtract a minute and eight seconds from that length, then print it. Is there a way I could process an input such as "5 minutes and 30 seconds"?
One possibility is to check each substring in the user's input and assign them to values:
s = input("video length? ")
minutes, seconds = [int(x) for x in s.split() if x.isdigit()]
The cast int(x) will save them as integers if desired:
print(minutes) # 5
print(seconds) # 30
Or a regular expression solution may be:
import re
minutes, seconds = map(int, re.findall('\d+', s))
print(minutes) # 5
print(seconds) # 30
Now you have the values to perform the resulting time calculation:
import datetime
# here, 100,1,1 are just placeholder values for year, month, day that are required to create a datetime object
usertime = datetime.datetime(100,1,1, minute=minutes, second=seconds)
calculation = usertime - datetime.timedelta(minutes=1, seconds=8)
Now you can display the result of the time calculation however you like:
print('{minutes} minutes and {seconds} seconds'.format(minutes=calculation.minute, seconds=calculation.second))
# 4 minutes and 22 seconds
You could use a regular expression if the format will always be the same (but it probably will not), then convert the appropriate string to an integer/ double.
I think that you are going about this incorrectly. It would be best to have two separate input fields that only accept integers. One for minutes and one for seconds. If you want more precision (i.e milliseconds) then just include another input field.
The main problem here is the format in which you will accept the input. You could force the user to input the time in just one format, for example, hours:minutes:seconds, in that case, the code below will calculate the total seconds:
inp = input('Video duration: ').split(':')
hours = 0
mins = 0
secs = 0
if len(inp) >= 3:
hours = int(inp[-3])
if len(inp) >= 2:
mins = int(inp[-2])
secs = int(inp[-1])
total_secs = hours * 3600 + mins * 60 + secs - 68
I oversimplified the code, it doesnt avoid user errors and edge cases
You can try :
import re
from datetime import datetime, timedelta
question = "How long is the video (mm:ss)? "
how_long = input(question).strip()
while not re.match(r"^[0-5]?\d:[0-5]?\d$", how_long): # regex to check if mm:ss digits are in range 0-5
how_long = input("Wrong format. " + question).strip()
mm_ss = how_long.split(":")
how_long_obj = datetime.strptime(f"{mm_ss[0]}:{mm_ss[1]}", '%M:%S')
print(f"{how_long_obj - timedelta(seconds=68):%M:%S}")
Output:
How long is the video (mm:ss)? 22:33
21:25
Python3 Demo - (Please turn Interactive mode On)
I'd like to execute a function a random number of times each day between set periods. Here's what I have so far:
def get_epochtime(dt=datetime.now()):
EPOCH = datetime(1970, 1, 1)
return (dt - EPOCH).total_seconds()
def get_todays_run_schedule(runs_per_day, run_between):
now = datetime.now()
window_start = now.replace(hour=run_between[0])
window_end = now.replace(hour=run_between[1])
the_schedule = [ get_epochtime(radar.random_datetime(start=window_start, stop=window_end)) for t in range(randint(runs_per_day[0], runs_per_day[1])) ]
the_schedule.sort()
print("Today I will run %s times" % len(the_schedule))
for run_at in the_schedule:
print("I will run at " + time.strftime("%Y-%m-%d %H:%M", time.localtime(run_at)))
return the_schedule
# we will run between 2 and 4 times per day between the hours of 10 AM and 5 PM.
schedule = get_todays_run_schedule((2, 4), (10, 17))
while(True):
now = datetime.now()
nowsecs = get_epochtime(now)
if now.hour == 0 and now.minute == 0 and now.second == 0:
schedule = get_todays_run_schedule()
if nowsecs in schedule:
execute_my_function
sleep(1)
Basically the idea is that at midnight and at first run, we come up with a run schedule which is a list of epoch times, the length of which is between two supplied integers. Each second we check the time and if the current time is within the list of run times, we execute our function. Finally, we sleep until the next second.
However, it isn't working at all. I suspect this might be because my datetime objects somehow include microseconds which is throwing off the comparison, but it could be because of something I'm not understanding about the nature of date time comparisons in python.
It's true that microseconds will be a problem for you here—both the objects in your list and the now will have microseconds, and running a loop only about once/second, the chance of any of those nows exactly matching an event timestamp are pretty slim.
But even if you fix that by truncating both now and the values in the list to seconds, that still won't solve the problem, it'll just make it an intermittent problem that's harder to debug. Consider what happens if you have an event at 15:25:26, and you start the loop at 15:25:25.907. You truncate that to 15:25:25, look it up, it's not there. Then you sleep for about a second, and call now(), and you get, say, 15:25:27.033. You truncate that to 15:25:27, look it up, and it's not there either.
Since you've already sorted the list, you can do something a whole lot simpler, which I'll demonstrate below. But first: While we're at it, the whole point of datetime objects is that they can do time comparisons, arithmetic, etc. directly, so you don't need to convert everything to numbers with something like your get_epochtime.
yesterday = datetime.today() - datetime.timedelta(days=1)
while True:
now = datetime.now()
if now.date() > yesterday:
schedule = get_todays_run_schedule()
yesterday = now.date()
while schedule and now >= schedule[0]:
del schedule[0]
execute_my_function
sleep(1)
(Obviously you'll also need to change get_todays_run_schedule to return a list of datetime objects instead of a list of floats to do it this way, but you should be able to figure that out.)
Also, notice that this way, we always know the time until the next event, so we don't need to loop around sleep(1) and keep waking the computer every second while it's on battery. You can just sleep(schedule[0] - now) when there is a next event, or sleep until midnight when there isn't. Or, maybe more simply, generate tomorrow's schedule when schedule goes empty, and then just sleep until its schedule[0].
In fact, if you think about it, you should be able to figure how to turn this into a loop in this form:
while True:
schedule = make_today_or_tomorrow_schedule()
for event in schedule:
while datetime.now() < event:
sleep(event - datetime.now())
execute_my_function
I know that I can cause a thread to sleep for a specific amount of time with:
time.sleep(NUM)
How can I make a thread sleep until 2AM? Do I have to do math to determine the number of seconds until 2AM? Or is there some library function?
( Yes, I know about cron and equivalent systems in Windows, but I want to sleep my thread in python proper and not rely on external stimulus or process signals.)
Here's a half-ass solution that doesn't account for clock jitter or adjustment of the clock. See comments for ways to get rid of that.
import time
import datetime
# if for some reason this script is still running
# after a year, we'll stop after 365 days
for i in xrange(0,365):
# sleep until 2AM
t = datetime.datetime.today()
future = datetime.datetime(t.year,t.month,t.day,2,0)
if t.hour >= 2:
future += datetime.timedelta(days=1)
time.sleep((future-t).total_seconds())
# do 2AM stuff
You can use the pause package, and specifically the pause.until function, for this:
import pause
from datetime import datetime
pause.until(datetime(2015, 8, 12, 2))
Slightly more generalized solution (based off of Ross Rogers') in case you'd like to add minutes as well.
def sleepUntil(self, hour, minute):
t = datetime.datetime.today()
future = datetime.datetime(t.year, t.month, t.day, hour, minute)
if t.timestamp() > future.timestamp():
future += datetime.timedelta(days=1)
time.sleep((future-t).total_seconds())
Another approach, using sleep, decreasing the timeout logarithmically.
def wait_until(end_datetime):
while True:
diff = (end_datetime - datetime.now()).total_seconds()
if diff < 0: return # In case end_datetime was in past to begin with
time.sleep(diff/2)
if diff <= 0.1: return
Building on the answer of #MZA and the comment of #Mads Y
One possible approach is to sleep for an hour. Every hour, check if the time is in the middle of the night. If so, proceed with your operation. If not, sleep for another hour and continue.
If the user were to change their clock in the middle of the day, this approach would reflect that change. While it requires slightly more resources, it should be negligible.
I tried the "pause" pacakage. It does not work for Python 3.x. From the pause package I extracted the code required to wait until a specific datetime and made the following def.
def wait_until(execute_it_now):
while True:
diff = (execute_it_now - datetime.now()).total_seconds()
if diff <= 0:
return
elif diff <= 0.1:
time.sleep(0.001)
elif diff <= 0.5:
time.sleep(0.01)
elif diff <= 1.5:
time.sleep(0.1)
else:
time.sleep(1)
adapt this:
from datetime import datetime, timedelta
from time import sleep
now = datetime.utcnow
to = (now() + timedelta(days = 1)).replace(hour=1, minute=0, second=0)
sleep((to-now()).seconds)
Slightly beside the point of the original question:
Even if you don't want to muck around with crontabs, if you can schedule python scripts to those hosts, you might be interested to schedule anacron tasks? anacron's major differentiator to cron is that it does not rely the computer to run continuously. Depending on system configuration you may need admin rights even for such user-scheduled tasks.
A similar, more modern tool is upstart provided by the Ubuntu folks: http://upstart.ubuntu.com/
This does not yet even have the required features. But scheduling jobs and replacing anacron is a planned feature. It has quite some traction due to its usage as Ubuntu default initd replacement. (I am not affiliated with the project)
Of course, with the already provided answer, you can code the same functionality into your python script and it might suit you better in your case.
Still, for others, anacron or similar existing systems might be a better solution. anacron is preinstalled on many current linux distributions (there are portability issues for windows users).
Wikipedia provides a pointer page: https://en.wikipedia.org/wiki/Anacron
If you do go for a python version I'd look at the asynchronous aspect, and ensure the script works even if the time is changed (daylight savings, etc) as others have commented already. Instead of waiting til a pre-calculated future, I'd always at maximum wait one hour, then re-check the time. The compute cycles invested should be negligible even on mobile, embedded systems.
Asynchronous version of Omrii's solution
import datetime
import asyncio
async def sleep_until(hour: int, minute: int, second: int):
"""Asynchronous wait until specific hour, minute and second
Args:
hour (int): Hour
minute (int): Minute
second (int): Second
"""
t = datetime.datetime.today()
future = datetime.datetime(t.year, t.month, t.day, hour, minute, second)
if t.timestamp() > future.timestamp():
future += datetime.timedelta(days=1)
await asyncio.sleep((future - t).total_seconds())
I know is way late for this, but I wanted to post an answer (inspired on the marked answer) considering systems that might have - incorrect - desired timezone + include how to do this threaded for people wondering how.
It looks big because I'm commenting every step to explain the logic.
import pytz #timezone lib
import datetime
import time
from threading import Thread
# using this as I am, check list of timezone strings at:
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TIMEZONE = pytz.timezone("America/Sao_Paulo")
# function to return desired seconds, even if it's the next day
## check the bkp_time variable (I use this for a bkp thread)
## to edit what time you want to execute your thread
def get_waiting_time_till_two(TIMEZONE):
# get current time and date as our timezone
## later we remove the timezone info just to be sure no errors
now = datetime.datetime.now(tz=TIMEZONE).replace(tzinfo=None)
curr_time = now.time()
curr_date = now.date()
# Make 23h30 string into datetime, adding the same date as current time above
bkp_time = datetime.datetime.strptime("02:00:00","%H:%M:%S").time()
bkp_datetime = datetime.datetime.combine(curr_date, bkp_time)
# extract the difference from both dates and a day in seconds
bkp_minus_curr_seconds = (bkp_datetime - now).total_seconds()
a_day_in_seconds = 60 * 60 * 24
# if the difference is a negative value, we will subtract (- with + = -)
# it from a day in seconds, otherwise it's just the difference
# this means that if the time is the next day, it will adjust accordingly
wait_time = a_day_in_seconds + bkp_minus_curr_seconds if bkp_minus_curr_seconds < 0 else bkp_minus_curr_seconds
return wait_time
# Here will be the function we will call at threading
def function_we_will_thread():
# this will make it infinite during the threading
while True:
seconds = get_waiting_time_till_two(TIMEZONE)
time.sleep(seconds)
# Do your routine
# Now this is the part where it will be threading
thread_auto_update = Thread(target=function_we_will_thread)
thread_auto_update.start()
It takes only one of the very basic libraries.
import time
sleep_until = 'Mon Dec 25 06:00:00 2020' # String format might be locale dependent.
print("Sleeping until {}...".format(sleep_until))
time.sleep(time.mktime(time.strptime(sleep_until)) - time.time())
time.strptime() parses the time from string -> struct_time tuple. The string can be in different format, if you give strptime() parse-format string as a second argument. E.g.
time.strptime("12/25/2020 02:00AM", "%m/%d/%Y %I:%M%p")
time.mktime() turns the struct_time -> epoch time in seconds.
time.time() gives current epoch time in seconds.
Substract the latter from the former and you get the wanted sleep time in seconds.
sleep() the amount.
If you just want to sleep until whatever happens to be the next 2AM, (might be today or tomorrow), you need an if-statement to check if the time has already passed today. And if it has, set the wake up for the next day instead.
import time
sleep_until = "02:00AM" # Sets the time to sleep until.
sleep_until = time.strftime("%m/%d/%Y " + sleep_until, time.localtime()) # Adds todays date to the string sleep_until.
now_epoch = time.time() #Current time in seconds from the epoch time.
alarm_epoch = time.mktime(time.strptime(sleep_until, "%m/%d/%Y %I:%M%p")) # Sleep_until time in seconds from the epoch time.
if now_epoch > alarm_epoch: #If we are already past the alarm time today.
alarm_epoch = alarm_epoch + 86400 # Adds a day worth of seconds to the alarm_epoch, hence setting it to next day instead.
time.sleep(alarm_epoch - now_epoch) # Sleeps until the next time the time is the set time, whether it's today or tomorrow.
What about this handy and simple solution?
from datetime import datetime
import time
pause_until = datetime.fromisoformat('2023-02-11T00:02:00') # or whatever timestamp you gonna need
time.sleep((pause_until - datetime.now()).total_seconds())
from datetime import datetime
import time, operator
time.sleep([i[0]*3600 + i[1]*60 for i in [[H, M]]][0] - [i[0]*3600 + i[1]*60 for i in [map(int, datetime.now().strftime("%H:%M").split(':'))]][0])
Instead of using the wait() function, you can use a while-loop checking if the specified date has been reached yet:
if datetime.datetime.utcnow() > next_friday_10am:
# run thread or whatever action
next_friday_10am = next_friday_10am()
time.sleep(30)
def next_friday_10am():
for i in range(7):
for j in range(24):
for k in range(60):
if (datetime.datetime.utcnow() + datetime.timedelta(days=i)).weekday() == 4:
if (datetime.datetime.utcnow() + datetime.timedelta(days=i, hours=j)).hour == 8:
if (datetime.datetime.utcnow() + datetime.timedelta(days=i, hours=j, minutes=k)).minute == 0:
return datetime.datetime.utcnow() + datetime.timedelta(days=i, hours=j, minutes=k)
Still has the time-checking thread check the condition every after 30 seconds so there is more computing required than in waiting, but it's a way to make it work.