I have a code which starts a main function. In this function have a while loop which should starts program when certain time comes. I have set this time in morning (start time), evening(end time) variables. It is in while loop and it works, but only if I start the program the day I want to use it. For example: When I start it Monday evening (20:00) and start time(morning variable) is from 8:00 (next day), it will continue loop
print("Waiting for the right time") <=(doing this)
even if that time the next day comes. But It works when I start it the next day at 6:00 or so...
Can someone explain me, why this happens?
Here is the code
import datetime
from time import sleep
from datetime import date
#variables
now = datetime.datetime.now()
morning = now.replace(hour=8, minute=0, second=0, microsecond=0)
evening = now.replace(hour=16, minute=15, second=0, microsecond=0)
#function for time-setting
def time_in_range(morning, evening, x):
if morning <= evening:
return morning <= x <= evening
else:
return morning <= x or x <= evening
timerange = time_in_range(morning, evening, now)
#main function
def main():
while True:
# Time period check
if date.today().weekday() < 5 and date.today().weekday() >= 0:
dayz = True
else:
dayz = False
if dayz != True:
print("Waiting for the day")
sleep(3600)
continue
now = datetime.datetime.now()
timerange = time_in_range(morning, evening, now)
if timerange != True: # HERE IT MAKES THE TROUBLE
print("Waiting for the right time")
sleep(200)
continue
print("do something")
main()
print("end of code")
When you call .replace() to set the morning and evening times, it keeps the current date as part of the datetime object. So if you were to call it a day before, the dates would be set to the previous day's date, and thus .now() will never be in between the previous day's time range.
E.g. if on January 1st you make the calls to set morning and evening, the stored datetimes will be "January 1st 8am" and "January 1st 4pm". The next time when your loop is checking, it asks "Is January 2nd 10am between January 1st 8am and January 1st 4pm" and of course the answer is no, because January 1st was the day before.
You probably want to use the datetime.time class instead of the datetime.datetime class, if you're only wanting to check for time. Alternatively, you could set the date portion of your evening and morning datetimes to the specific date you want to match (but that wouldn't help for repeating weekly).
import datetime
from time import sleep
from datetime import date
#variables
now = datetime.datetime.now()
morning = now.replace(hour=8, minute=0, second=0, microsecond=0)
evening = now.replace(hour=16, minute=15, second=0, microsecond=0)
#function for time-setting
def time_in_range(morning, evening, x):
# Updated code
morning = x.replace(hour=8, minute=0, second=0, microsecond=0)
evening = x.replace(hour=16, minute=15, second=0, microsecond=0)
if morning <= evening:
return morning <= x <= evening
else:
return morning <= x or x <= evening
timerange = time_in_range(morning, evening, now)
print(timerange)
#main function
def main():
while True:
# Time period check
if date.today().weekday() < 5 and date.today().weekday() >= 0:
dayz = True
else:
dayz = False
if dayz != True:
print("Waiting for the day")
sleep(3600)
continue
now = datetime.datetime.now()
timerange = time_in_range(morning, evening, now)
if timerange != True: # HERE IT MAKES THE TROUBLE
print("Waiting for the right time")
sleep(200)
continue
print("do something")
main()
print("end of code")
Related
I'm trying to make a python bot and as one off the commands i want to dsiplay how long it will be until the server restarts (11pm est) every day.
this is the code i wrote but it gives some weird outputs sometimes, when it's midnight it returns 40 hours until restart.
Can anyone help me out here?
#client.command()
async def gettime(self):
now = datetime.now()
# 11 est == 17 gmt+1
reset = datetime.strptime('16:00', '%H:%M')
if now == reset:
await self.send('the restart is happening now')
elif now < reset:
untilrestarthour = reset.hour - now.hour
untilrestartminute = 60 - now.minute
await self.send(f'the restart is happening in {untilrestarthour} hours and {untilrestartminute}''s ')
elif now > reset:
untilrestarthour = 24 - (now.hour - reset.hour)
untilrestartminute = 60 - now.minute
await self.send(f'the restart is happening in {untilrestarthour} hours and {untilrestartminute} minute''s ')
else:
await self.send("error")
In current version you substract from 24h and from 60minutes so finally you substract from 24h+60minutes which gives 25h. You would have to do something like
untilrestarthour = reset.hour - now.hour
if now.minute > 0:
untilrestarthour -= 1
untilrestartminute = 60 - now.minute
else:
untilrestartminute = 0
But maybe better you should use correct date instead of 1900-01-01 and then you can use now - reset or reset - now to calculate hours and minutes correctly.
from datetime import datetime, timedelta
now = datetime.now()
reset = now.replace(hour=16, minute=0)
#reset += timedelta(days=1) # next day
print(' now:', now)
print('reset:', reset)
print('reset-now:', reset-now)
print('now-reset:', now-reset)
if now == reset:
print('the restart is happening now')
elif now < reset:
print('reset in the future:', reset-now)
elif now > reset:
print('reset in the past:', now-reset)
else:
print("error")
Result
now: 2020-05-20 17:49:04.029570
reset: 2020-05-20 16:00:04.029570
reset-now: -1 day, 22:11:00
now-reset: 1:49:00
reset in the past: 1:49:00
The only problem is that now - reset (reset - now) creates object datetime.timedelta which can generate string 1:49:00 but it can't gives separatelly hours 1 and minutes 49. It gives only total seconds and you have to manually conver seconds to hours and minutes
print('reset:', reset)
print(' now:', now)
diff = (reset-now)
print('diff:', diff)
seconds = diff.seconds
print('seconds:', seconds)
hours = seconds//3600
seconds = seconds % 3600
minutes = seconds // 60
seconds = seconds % 60
print('hours:', hours, '| minutes:', minutes, '| seconds:', seconds)
Result:
reset: 2020-05-21 16:00:37.395018
now: 2020-05-20 18:00:37.395018
diff: 22:00:00
seconds: 79200
hours: 22 | minutes: 0 | seconds: 0
So I'm fairly new to Python and I am trying to write a code for a timer. My code is supposed to get the hour, minute, whether it's AM or PM, and a message that they want the program to print out when their timer is done. As of now, the program asks several questions and stores them in variables, but doesn't print out the message when it is done.
I have tried looking at each part of the code and the code is fairly simple so I don't understand why this is occurring.
# Set up variables
hour = int(input('What should the hour be? '))
minute = input('What should the minute be? ')
ampm = input('A.M. or P.M.? ')
if (ampm == 'A.M.'):
if (hour == 12):
hour = 0
else:
hour = hour
if (ampm == 'P.M.'):
if (hour == 12):
hour = hour
else:
hour = hour + 12
message = input('What should the message be? ')
import datetime
current_hour = datetime.datetime.today().strftime('%H')
current_minute = datetime.datetime.today().strftime('%M')
alarm = True
# Set up loop
while (alarm):
if (hour != datetime.datetime.today().strftime('%H')):
alarm = True
else:
if (minute == datetime.datetime.today().strftime('%M')):
print(message)
alarm = False
else:
alarm = True
It is supposed to print out the message that the user inputted. It's not doing that.
The variable of hour returns an int value and datetime.datetime.today().strftime('%H') returns string so your program get in the infinite loop.Change condition like
if (hour != int((datetime.datetime.today().strftime('%H')))):
I have a code with this ↓ part in it, which should do something when the time and day come. It has outer and inner time and day checks (while loops).
Outer for the situation in which code starts processing in time (or day) which is not in the timerange for code processing - it should wait until that time (or day). And it works, but only in situation when I set it like 10 minutes before the timerange (code processing time). When I set it like a night before, it won't works and it stops in print("timerange wait") It shows False even it should be True. Is there a problem because it is not in the same day? Or something else? Please give me some advices.
Here is the simple version of code (without unnecessary parts )
import os
import datetime
from time import sleep
from datetime import date
#setting used variables
now = datetime.datetime.now()
morning = now.replace(hour=8, minute=0, second=0, microsecond=0)
evening = now.replace(hour=18, minute=9, second=0, microsecond=0)
# function for check creating "timerange -start time, end time"
def time_in_range(morning, evening, x):
if morning <= evening:
return morning <= x <= evening
else:
return morning <= x or x <= evening
# main program for doing something
def main():
while True:
# Time period check - Check if time and weekdays are not out of range
# if not in range will wait till the time
if date.today().weekday():
dayz = True
else:
dayz = False
now = datetime.datetime.now()
timerange = time_in_range(morning, evening, now)
if timerange != True:
print("waiting for function-time")
sleep(10)
continue
if dayz != True:
print("waiting for function-days")
sleep(3600)
continue
while True:
print("do something")
#check if during while loop there wasn't date, time change (out of timerange etc)
if date.today().weekday():
dayz = True
else:
dayz = False
now = datetime.datetime.now()
timerange = time_in_range(morning, evening, now)
if timerange != True:
print("break inner loop-timerange")
break
if dayz != True:
print("break inner loop-dayz")
break
print("do something -main work")
#program starts here
timerange = time_in_range(morning, evening, now)
# check if today is weekday (outer loop)
if date.today().weekday():
dayz = True
else:
dayz = False
# if today is not a weekday wait till weekday (outer loop)
#for situation where the code started not in weekday
while dayz != True:
print("days wait")
sleep(3600)
dayz = date.today().weekday()
if dayz == True:
break
# If it is not processing time, wait until it becomes
# for the situation where code started not in "timerange"
while timerange != True:
print("timerange wait") # ---------HERE IT STOPS---------
# But it works fine, when I set it like one hour before 'timerange' or so...
sleep(10)
now = datetime.datetime.now()
timerange = time_in_range(morning, evening, now)
print(timerange)
if timerange == True:
break
# Do the main function
main()
# Let know when code ends
print("Over of Code")
I defined two variables for previous days (one for friday and one for monday to thursday). After giving the condition, it asks for varible not defied, below is the code.
import datetime
d = datetime.date.today()
if d.weekday() == 0:
tdelta = datetime.timedelta(days=3)
friday = d - tdelta
else:
tdelta1 = datetime.timedelta(days=1)
prev_day = d - tdelta1
if data_date == friday:
print("Data as on", friday, "for page")
elif data_date == prev_day:
print("Data as on", prev_day, "for page")
else:
print("Data update required.")
For the above code, error is shown as 'prev_day' not defined. Please help.
I need some help with get pass on the if statement. I have a problem with if statement as I am trying to get pass when I am trying to compare on the values using three variables.
start_time = '22:35'
current_time = '23:48'
stop_time = '00:00'
if current_time == start_time:
print "the program has started"
elif start_time != current_time < stop_time:
print "program is half way"
elif current_time > stop_time:
print "program has finished"
I can get pass on each if statement with no problem, but my problem is when I have the variable start_time with the value 22:35 which it is not equal to current_time value 23:48. So how I can compare with the values between the start_time and current_time as I want to compare to see if it is less than the value 00:00 from the variable stop_time?
I want to check if the value from the variable stop_time which is less than the current_time and start_time.
Just imagine you are watching the tv program which it start at 22:35 in your current time. You are watching which it is less than before the program finish at 00:00, so you check the time again later before the finish time 00:00, it say it is still half way through. Then you check it later at your current time which it is after than 00:00 so it say the program has finished.
Well on my code, I will always get pass on the elif current_time > stop_time: as i always keep getting the print "program has finished" which I should have print "program is half way" instead.
How can you compare three values between the variables start_time and current_time to see if it is less than and check to see if it is less the value 00:00 from the variable stop_time?
EDIT: Here is what I use them as a string when i am getting the hours and minutes from the date format especially year, month, day, hours, minutes and seconds
start_date = str(stop_date[0]) #get start_date date format from database
stop_date = str(stop_date[1]) #get start_date date format from database
get_current_time = datetime.datetime.now().strftime('%H:%M')
get_start_time = time.strptime(start_date, '%Y%m%d%H%M%S')
start_time = time.strftime('%H:%M', get_start_time)
get_stop_time = time.strptime(stop_date, '%Y%m%d%H%M%S')
stop_time = time.strftime('%H:%M', get_stop_time)
current_time = str(get_current_time)
Using two comparisons and the and logical we could create something like this:
if current_time > start_time and current_time < stop_time:
#do work
But that actual problem is dealing with date and time
current_time = datetime.now() #lets say this is 2016, 2, 12, 17:30
start_time = datetime.datetime(2016,2,12,16,30) # or datetime.strptime(start_time)
end_time = datetime.datetime(2016,2,13,0,0)
if current_time == start_time:
print "the program has started"
elif current_time > start_time and current_time < stop_time:
print "Program is still running"
elif current_time > stop_time:
print "program has finished"