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')
Related
good day! How to properly apply a FOR loop to a given function?
thanks for the tips:)
from datetime import timedelta
from apps.tickets.models import PatientConsultationTicket
def tickets_change():
tickets = PatientConsultationTicket.object.all()
one_day = tickets.created_at + timedelta(days=1)
if datetime.now() > one_day:
tickets.status = 'rd'
tickets.save()
elif datetime.now() < one_day:
tickets.status = 'e'
tickets.save()
To answer your question that's how you can iterate on the tickets :
from datetime import timedelta
from apps.tickets.models import PatientConsultationTicket
def tickets_change():
tickets = PatientConsultationTicket.objects.all()
for ticket in tickets:
one_day = ticket.created_at + timedelta(days=1)
if datetime.now() > one_day:
ticket.status = 'rd'
ticket.save()
elif datetime.now() < one_day:
ticket.status = 'e'
ticket.save()
Though, it's probably not the best way to do what you want.
Instead you should probably use an "UPDATE" query (not tested but it could look to something like that):
PatientConsultationTicket.objects.filter(created_at__gte=datetime.now()-timedelta(days=1)).update(status='rd')
PatientConsultationTicket.objects.filter(created_at__lte=datetime.now()-timedelta(days=1)).update(status='e')
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
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!!!
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.
I have a function hello_world () that I would like to call every hour (1:00, 2:00, 3:00, etc).
I'm a beginner here and not totally comfortable with writing loops.
I have the following code, but it stops after 23 hours. I am not sure how to loop the loop such that everything repeats at the end of the day!
def sched ():
i = 0
for (i <= 23):
x = datetime.today()
current_hour = datetime.now().hour
y=x.replace(day=x.day+1, hour=i, minute=00, second=00, microsecond=00)
delta_t=y-x
secs=delta_t.seconds+1
t=Timer(secs, hello_world)
t.start()
i = i + 1
I also realize this may not be the most efficient way of writing this code, so I am open to suggestions on how to improve.
Do you know about modulo operator (%)? i % 24 will return the remainder after dividing by 24, so i will be 0, 1, .. 23, 0 .. etc
def sched ():
i = 0
while True:
x = datetime.today()
current_hour = datetime.now().hour
y=x.replace(day=x.day+1, hour=i, minute=00, second=00, microsecond=00)
delta_t=y-x
secs=delta_t.seconds+1
t=Timer(secs, hello_world)
t.start()
i = i + 1
i = i % 24
That is because you limited your loop to i <= 23. You can change it to this:
i = 0
while True:
x = datetime.today()
current_hour = datetime.now().hour
y=x.replace(day=x.day+1, hour=i, minute=00, second=00, microsecond=00)
delta_t=y-x
secs=delta_t.seconds+1
t=Timer(secs, hello_world)
t.start()
i = (i + 1) % 24
Using (i + 1) % 24 guarentees that i will never be greater than 23. More about the modulus operator here.