Wait until specific time - python

I'm writing a program that will do something if now == specific time and day and wait till that time if is not equal.
I have a morning, evening, days values, which shows start time, end time and today's day. I would like to make a program that check if today is a weekday and specific time (between morning and evening) if True to do something and if even one of these is False, gonna wait till that time and after that do something.
I did it with while loop but when it starts with False value(not in right time) it continue printing False even if that time came and value should change to True but it shows True when I start it in right time.
Here is the code:
import datetime
from datetime import date
from time import sleep
#setting values
now = datetime.datetime.now()
morning = now.replace(hour=9, minute=00, second=0, microsecond=0)
evening = now.replace(hour=16, minute=0, second=0, microsecond=0)
days = now.strftime("%A")
#check if time is in range and return True or False
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)
#check if today is weekday
if date.today().weekday() == 0:
dayz = True
else:
dayz = False
# If today weekday and time range do something
if dayz == True and timerange == True:
print("Yes")
while dayz == False or timerange == False:
sleep(5)
timerange = time_in_range(morning, evening, now)
print(timerange) #this printing false even if is right time.
# But it shows True when I turn it on in right time

You only initialize your now variable once and never update its value to the current now. You should update the value inside the while loop, for example:
while dayz == False or timerange == False:
sleep(5)
now = datetime.datetime.now()
...

If you are interested in checking just the hours to determine morning and evening as I can see in your code, you can use below snippet:
from datetime import datetime
from datetime import timedelta
from time import sleep
morning_hour = 9
evening_hour = 16
while True:
curr_time = datetime.now()
print("Current time : {0}".format(curr_time))
if curr_time.hour < morning_hour or curr_time.hour > evening_hour or not curr_time.isoweekday():
print("Job start conditions not met. Determining sleep time")
add_days = 0
current_day = curr_time.weekday() == 4
# Add 3 days for fridays to skip Sat/Sun
if current_day == 4:
add_days = 3
# Add 2 days for Saturdays to skip Sunday
elif current_day == 5:
add_days = 2
else:
add_days = 1
next_window = (curr_time + timedelta(days=add_days)).replace(hour=9, minute=0,second=0,microsecond=0)
delta = next_window - datetime.now()
print("Sleep secs : {0}".format(delta.seconds))
sleep(delta.seconds)
else:
print("Do something")
break

Related

How to Execute a Function after A particular time Like Click a button at 10 am or 11 am?

I tried these codes.
x = 6
while 1:
if x < 0.999:
break
#execute you function after 6 seconds.
x -= 0.01
sleep(0.01)
But i need to execute on a particular time . So i tried this:
if (self.is_hour_between("09:55:00", "11:20:00")) == True:
#your function
else:
#your function
def time_between(self, start, end):
# Time Now
now = datetime.now().time()
# Format the datetime string
time_format = "%H:%M:%S"
# Convert the start and end datetime to just time
start = datetime.strptime(start, time_format).time()
end = datetime.strptime(end, time_format).time()
is_between = False
is_between |= start <= now <= end
is_between |= end <= start and (start <= now or now <= end)
return is_between
i wanted to run the function at exactly 10 Am and 11Am .If its not the time then wait for it.else if its the time then go for it without waiting
Anwser :
import datetime
import time
while True:
current_dt = datetime.datetime.now()
time_a = datetime.datetime(current_dt.year, current_dt.month, current_dt.day, 9, 55)
time_b = datetime.datetime(current_dt.year, current_dt.month, current_dt.day, 11, 20)
if (time_a<current_dt) and (time_b > current_dt):
print('ok')
else:
time.sleep(60)

how do you program a calendar that can tell you the days ago/ from now (past/future dates) of a specific date you enter in

I am trying to program a calendar that checks how many days from now/ ago (past and present) from raw_input. I need a loop that counts the days through the current year and adds it to a variable called: Total_days and this loop has to go through each year until it hits the current date that the code ran on. The end result is that the output gives you the date you entered in a complete sentence: eg. "10/08/1700 was ___ days ago" Basically my teacher explained that the past days has to add up until it hits that certain date using a loop(loops are required. This is an assignment, i cant use any other functions like delta, but loops and datetime stuff is good!) and then for the future it has to say how many days from now until that futuristic date happens using loops. I am very stumped and i need your guys' help.
Heres what i got so far:
import datetime
input_date = raw_input("Enter in full format (mm/dd/yyyy):")
year = input_date[6:10]
yeara = int(year)
montha = int(input_date[1:2])
daya = int(input_date[4:5])
from datetime import datetime
from datetime import date
now = datetime.now()
year = now.year
month = now.month
day = now.day
def isleapYear(year):
if year % 4 == 0:
check = True
if year % 100 == 0:
check = False
if year % 400 == 0:
check = True
total_days = 0
n = 12
moNum = [0,31,28,31,30,31,30,31,31,30,31,30,31]
while n > montha:
if yeara > year:
if year == isleapYear(year):
total_days += 366
elif year != isleapYear(year):
total_days += 365
if montha == month:
break
total_days += int(moNum[n])
if n == 02:
if isleapYear(year) == True:
total_days += 1
n -= 1
ny = 365
h = total_days
if yeara > year:
if year == isleapYear(year):
total_days += 366
elif year != isleapYear(year):
total_days += 365
if yeara>year:
time = "future"
if yeara<year:
time = "past"
if yeara==year:
if montha>month:
time = "future"
if montha<month:
time = past
if montha == month:
if daya>day:
time = "future"
if daya<day:
time = "past"
if daya==day:
time = "present"
print str(h.days) + " days in the " + str(time)
Thanks for helping out! i appreciate your help :)
Must you use a loop? Else, you can build from the following:
refdatestr = "2010/08/23"
refdate = datetime.strptime(refdatestr, "%Y/%m/%d")
now = datetime.now()
difference_days = (now-refdate).days
difference_days is a datetime.timedelta object. If refdate (or refdatestr) was in the future, this would be negative.
Here is an updated code, with everything fixed:
import datetime
input_date = raw_input("Enter in full format (mm/dd/yyyy):")
year = input_date[6:10]
yeara = int(year)
montha = int(input_date[1:2])
daya = int(input_date[4:5])
from datetime import datetime
from datetime import date
now = datetime.now()
year = now.year
month = now.month
day = now.day
def isleapYear(year):
if year % 4 == 0:
check = True
if year % 100 == 0:
check = False
if year % 400 == 0:
check = True
end_date = input_date
start_date = now
delta = date(year,month,day)
delta2 = date(yeara,montha,daya)
h = delta-delta2
if yeara>year:
time = "future"
if yeara<year:
time = "past"
if yeara==year:
if montha>month:
time = "future"
if montha<month:
time = past
if montha == month:
if daya>day:
time = "future"
if daya<day:
time = "past"
if daya==day:
time = "present"
print str(h.days) + " in the " + str(time)
The most important thing that you forgot is that there are functions in datetime that will automatically find the number of days till the input...
Hope this helps!!!

Program idle while comparing two dates in while statement

Don't know how to properly describe my problem, but when I compare two datetime objects in while statement the whole program stops working.
I have a method work()
import time
import datetime
def work():
now = None
intr = 10.0
d = datetime.datetime.utcnow()
least_time = datetime.datetime.combine(datetime.datetime.today(), datetime.time(10, 10, 00))
finish = datetime.datetime.combine(datetime.datetime.today(), datetime.time(10, 10, 20))
if datetime.datetime.today().weekday() == 0:
least_time = datetime.datetime.combine(datetime.datetime.today(), datetime.time(11,10,00))
finish = datetime.datetime.combine(datetime.datetime.today(), datetime.time(11,10,20))
while d <= finish:
d = datetime.datetime.utcnow()
if intr > 1 and d >= least_time:
intr = 1
print("Interval set to 1 sec")
if now == None:
now = time.time()
if time.time() - now >= intr:
print("Work")
print("_____")
now = None
print("End")
And, if I call print() or something else before that method:
print("1")
print("2")
print("3")
work()
The program just idle and do nothing.
What happens depends on your current time zone.
The call to datetime.datetime.utcnow() gives a datetime in UTC,
whereas datetime.datetime.today() gives you current datetime for your time zone (which you machine has):
Changing:
d = datetime.datetime.utcnow()
to:
d = datetime.datetime.now()
or to:
d = datetime.datetime.today()
would fix your problem.

How to compare hours and minutes?

I have four variables:
start_hour = '12'
start_minute = '00'
end_hour = '22'
end_minute = '30'
and from datetime:
current_hour = datetime.now().hour
curren_minute = datetime.now().minute
And I want to compare if the current time is within the range:
if int(start_hour) <= current_hour and int(end_hour) >= current_hour:
something
But how to implement this with minutes?
You can use datetime.timedelta to do the comparisons reliably. You can specify a delta in different units of time (hours, minutes, seconds, etc.) Then you don't have to worry about converting to hours, minutes, etc. explicitly.
For example, to check if the current time is more than an hour from the start_time:
if abs(datetime.now() - start_time) > datetime.timedelta(hours=1):
# Do thing
You can also use timedelta to shift a time by a given amount:
six_point_five_hours_from_now = datetime.now() + datetime.timedelta(hours=6, minutes=30)
The nice thing about timedelta apart from easy conversions between units is it will automatically handle time differences that span multiple days, etc.
A much better way to go about this would beto convert both times to minutes:
start_time = int(start_hour)*60 + int(start_minute)
end_time = int(end_hour)*60 + int(end_minute)
current_time = datetime.now().hour*60 +datetime.now().minute
if start_time <= current_time and end_time >= current_time:
#doSomething
If you need to include seconds, convert everything to seconds.
What about:
>>> import datetime
>>> now = datetime.datetime.now()
>>> breakfast_time = now.replace( hour=7, minute=30, second=0, microsecond=0 )
>>> lunch_time = now.replace( hour=12, minute=30, second=0, microsecond=0 )
>>> coffee_break = now.replace( hour=16, minute=00, second=0, microsecond=0 )
>>> breakfast_time <= lunch_time <= coffee_break
True
A simple and clear way to do it all with just datetime objects is:
now = datetime.now()
start = now.replace(hour = int(start_hour), minute = int(start_minute))
end = now.replace(hour = int(end_hour), minute = int(end_minute))
if start <= now <= end:
print('something')

So I want to make a clock in Python that displays both A.M. and P.M

So I have this here.
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours = 2
if Hours == 12:
Hours = 1
Minutes = 0
break
ReadLine = ("\t{0:>2} : {1:>2}\r").format(Hours, Minutes)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
Just for the record, I have made sure that the indentations are correct, they look a little screwy here. And I realize that I have nothing set for A.M./P.M. as of yet.. Any help is appreciated for this noob.
Thank you - Matt.
Edit:
>>> 2: 0 2: 0 2: 0
This is what is printing out now, the minutes have not updated. I'm obviously missing something. Once again thanks for any help, and I am sorry if this is a repeat, I have searched for an answer, but none was found. Thanks - Matt.
Edit #2- I figured it out. I used a bit of both of the answers, and whilst I accept the fact that it will be slow it does what I want it to do.
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
AM_PM = "AM" if Hours < 12 else "P.M"
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours += 1
if Hours == 24:
Hours = 1
Minutes = 0
break
ReadLine = ("\t{:>2} : {:>2} {}\r").format(Hours, Minutes, AM_PM)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
You know, it seems no matter how hard I try, I cannot get this darned indentation to look right. Oh well, I hope you can understand it's just tabbed a bit to the right.
your code print nothing because you put the code that print to stdout inside the if statements. so it would print only when Minutes == 60 and Hours == 12 (which will never happend because of you dont increament Hours as meantioned in the comments.
try this:
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
ampm = "AM"
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours += 1
if Hours == 12:
Hours = 1
Minutes = 0
ampm = ("AM" if (ampm == "PM") else "PM")
ReadLine = ("\t{0:>2} : {1:>2} {2} \r").format(Hours, Minutes,ampm)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
import datetime
then = now = datetime.datetime.now()
minutes = 0
hours = 0
while True:
now = datetime.datetime.now()
if (now-then).total_seconds() > 60:
then += datetime.timedelta(minutes=1)
minutes += 1
if minutes == 60:
minutes = 0
hours += 1
if hours == 24:
hours = 0
am_pm = "AM" if hours < 12 else "PM"
print("{:>2}:{:>02} {}".format((hours+11)%12+1, minutes, am_pm))
Note that I do away with time.sleep as it's not guaranteed to sleep for exactly the time requested (indeed you will always be running slightly slow by that clock) and instead compare a current time to the last time a minute passed and see if the total seconds are more than 60. If so, increment minutes, if minutes is 60, increment hours and check for rollover and am_pm switch. Afterwards, print the time.
If you're wanting to stretch your legs a little, try implementing it in a class! Ooh ooh, and threading too!
import datetime
import threading
import queue
class Clock(object):
def __init__(self, current_time=None):
if isinstance(current_time, datetime.datetime):
hours, minutes = current_time.hour, current_time.minute
else:
hours = minutes = 0
self.hours = hours
self.minutes = minutes
self.q = queue.Queue()
def checkTime(self):
try:
self.q.get_nowait() # time has updated, or exception thrown
self.updateTime()
self.q.task_done()
except queue.Empty:
pass # time hasn't updated
def updateTime(self, num_mins=1):
self.minutes += 1
if self.minutes == 60:
self.minutes = 0
self.hours += 1
if self.hours == 24:
self.hours = 0
print(self)
def minutePassed(self):
then = datetime.datetime.now()
while True:
now = datetime.datetime.now()
if (now-then).total_seconds() > 60:
then += datetime.timedelta(minutes=1)
self.q.put('_') # put something there, doesn't matter what
def __str__(self):
am_pm = "AM" if self.hours < 12 else "PM"
return "{:>2}:{:>02} {}".format((self.hours+11)%12+1,
self.minutes, am_pm)
def start(self):
t = threading.Thread(target=self.minutePassed)
t.daemon=True
t.start()
while True:
self.checkTime()
clock = Clock(datetime.datetime.now())
clock.start()

Categories