I am making a program that determines what period in school you are in; the schedules differ on certain days so you can just run the program instead of finding out what schedule you are on.
I am using the 'DateTime' import; but the problem is certain classes may start at let's say 7:45 and end at 9:50. The way I am programming the two times contradict each-other so the text wont be displayed.
here is the snippet of code:
if sch == "A":
if hour >= 7 and min >= 45:
if hour <= 9 and min <= 50:
print("It is period 1; Class ends at 9:50AM")
It was determined previously in the program that we are on schedule 'A' which starts at 7:45AM and ends at 9:50AM. In short I want it to display the message whilst in between those two times.
Use datetime for this task:
from datetime import datetime
begin = '07:45:00'
end = '09:50:00' # for example
current_time = '10:32:13'
FMT = '%H:%M:%S' # format time
if sch == "A":
if datetime.strptime(begin, FMT) < \
datetime.strptime(current_time, FMT) < \
datetime.strptime(end, FMT):
print("It is period 1; Class ends at 9:50AM")
you can try this:
from datetime import time
if sch == "A":
if time(hour=7, minute=45) <= time(hour=hour, minute=minute) <= time(hour=9, minute=45):
print("It is period 1; Class ends at 9:50AM")
As I commented your logic is off because you don't allow for minutes other than anything in the 45-50 range, your are using datetimes so stick to comparing datetimes.time's seeing if the hour and minute are within the range 7:45-9:50.
from datetime import time
# cretate a start and end time
start, end = time(7, 45, 0), time(9, 50, 0)
# pass whatever hour and min are in your code to time
hour_min = time(7, 46)
# check the times falls in the range 7:45-9:50
if start <= hour_min <= end:
print("It is period 1; Class ends at 9:50AM")
Related
I am working on making calibrations for the Raspberry Pi Weather Station I have created using the Sense HAT. The offset between the actual temperature and the reading received from the Pi increases at a certain time of day (when the sun hits the system). I want to subtract a larger number from the Sense HAT temp during this time and revert to the lower number at all other instances.
I attempted to use datetime module to set up the beginning and and end times for the more significant calibration. I set up the current time in a separate variable.
time = datetime.time()
time_start = datetime.time(12,30,00)
time_end = datetime.time(3,15,00)
if time_start < time and time_end > time:
temperature -= 10
else:
temperature -= 8
I expected the output to be a lower temperature reading but the program continues to subtract 8 degrees during this period instead of 10. I did some troubleshooting and when printing the "time" variable it prints as "00:00:00". This would explain why the program skips to the else statement and only subtracts 8.
Any idea on how to solve this?
Using datetime.time() is the equivalent of using time(0, 0, 0).
What you want instead is to obtain the current time, which you can do through datetime.now().
import datetime
time = datetime.datetime.now().time()
time_start = datetime.time(12,30,00)
time_end = datetime.time(3,15,00)
if time_start < time and time_end > time:
temperature -= 10
else:
temperature -= 8
I am writing a script which will record the user activity in a certain period of time every day. The periods are taken from a JSON response of an API, like this:
[{"working_day": "mon", "work_start_at": "09:00", "work_end_at": "18:00"},
{"working_day": "tue", "work_start_at": "09:00", "work_end_at": "15:00"}]
Let's assume that I can parse these strings in a datetime() format.
I want to run my function accordingly to these periods and stop my function after "work_end_at". I found numerous example of how to run after certain amount of seconds, how to run every day (Python lib schedule) and examples with bash crontab. But nothing of this works for me, because all I want is to start the script at a specific time and stop at a specific time. And then, run again when the next "shift" comes.
def start():
time_periods = working_periods_table.find_all()
today = datetime.datetime.now().isoweekday()
for day in time_periods:
if day["day"] == today:
start_time = day["work_start_at"]
end_time = day["work_end_at"]
schedule.every().week.at(start_time).do(record_activity(idle_time=300))
If I've understood what you're asking, you could use while loops. Have it periodically check the current time with the times for the shift beginning and end. Below is a guide of what I mean, but I'm not sure the comparisons will work.
from time import sleep
def start():
time_periods = working_periods_table.find_all()
today = datetime.datetime.now().isoweekday()
for day in time_periods:
if day["day"] == today:
start_time = day["work_start_at"]
end_time = day["work_end_at"]
while True:
if datetime.datetime.now() >= start_time:
while True:
schedule.every().week.at(start_time).do(record_activity(idle_time=300))
if datetime.datetime.now() >= end_time:
break
break
else:
sleep(100)
I have some way to start my process at certain time but can not stop at certain time, I think you might means after running at 1 hour, even it is not finished yet, still stop the program. in this case you might can use while loop
take a look with my scripts first this might helpful
import time
from time import strftime, localtime
import datetime
now = datetime.datetime.now()
year = int(now.strftime("%Y"))
month = int(now.strftime("%m"))
day = int(now.strftime("%d"))
hour = int(now.strftime("%H"))
start_time_t = datetime.datetime(year=year, month=month, day=day, hour=22, minute=0, second=0)
waiting_time = time.mktime(start_time_t.timetuple()) - time.time()
if waiting_time >= 0:
print('the program will be start after ' + time.strftime("%H hours and %M minutes", time.gmtime(waiting_time)))
time.sleep(waiting_time)
else:
start_time_t = datetime.datetime(year=year, month=month, day=day + 1, hour=00, minute=0, second=0)
waiting_time = time.mktime(start_time_t.timetuple()) - time.time()
print('the program will be start after ' + time.strftime("%H hours and %M minutes", time.gmtime(waiting_time)))
time.sleep(waiting_time)
It will runs my program every day at 10:00 PM, if pass 10:00 PM the program will runs on the beginning of text day.
If you want to run your script at specific time intervals, I will suggest the code below which I have used on my own script. So simple to implement.
import datetime
now = datetime.datetime.now()
print(now.year, now.month, now.day, now.hour, now.minute, now.second)
# 2015 5 6 8 53 40
while True:
now = datetime.datetime.now()
if 14 <= now.hour and 23=> now.hour:
# put your code here
Note that in this piece of code I consider 2 PM until 11 PM. And more important you have to get the current hour persistently in a loop.
If you have a specific day in your mind get your current day out of the loop and compare it to your get value !! It works for me.
I will attach my code, but basically I am importing a csv file with start times/end times for picking cases of a particular item. All the cases go to a "cart", which is identified by an ID number. I want to find the total time to pick all the cases. The format of the time is hh:mm:ss and, initially, I was using the datetime module but I could not figure out the documentation, so I ended up just converting all the times to seconds, subtracting end/start for each case, and adding that duration to the total time. In the end, converted total time to hours. Already had number of cases picked total, and divided by total time in hrs to get cases picked per hr. Is this correct logic? I got a number that was very, very low: 7.99 cases/hr, which leads me to believe my timing/duration code is incorrect (already checked that quantity was correct).
#instantiate totalTime to zero
totalTime = 0
#every line/row in file; assume already opened above
for line in lines:
#if there is a different case to pick, find the start time
if taskId != entryList[0]: #this is so it doesnt duplicate times
timestart = entryList[7]
colonStartIndex = timestart.find(":")
hourstart = int(timestart[0:colonStartIndex])
minutestart = int(timestart[colonStartIndex+1:colonStartIndex+3])
colonStartIndex2 = timestart.find(":", colonStartIndex+1)
secondstart = int(timestart[colonStartIndex2 +1:colonStartIndex2 +3])
start = hourstart*3600 + minutestart*60 + secondstart
#start = datetime(year=1, month=1, day=1,hour=hourstart,minute=minutestart,second=secondstart)
#start = datetime.time(start)
timeend = entryList[9]
colonEndIndex = timeend.find(":")
hourend = int(timeend[0:colonEndIndex])
minuteend = int(timeend[colonEndIndex+1:colonEndIndex+3])
colonEndIndex2 = timeend.find(":", colonEndIndex+1)
secondend = int(timeend[colonEndIndex2+1:colonEndIndex2+3])
end = hourend*3600 + minuteend*60 + secondend
#end = datetime(year=1,month=1,day=1,hour=hourend,minute=minuteend,second=secondend)
#end = datetime.time(end)
#duration = datetime.combine(date.today(), end) - datetime.combine(date.today(), start)
duration = end - start
if duration >= 0:
duration = duration
elif duration < 0:
duration = -1*duration
totalTime = totalTime + duration
taskId = entryList[0] #first entry in csv file of each line is cartID
totalTime = totalTime/3600
print(totalTime)
print(quantityCount)
avgNumCases = quantityCount/totalTime
print(avgNumCases)
Thank you so much for any help!! Also, I included the datetime stuff, commented out, so if you could suggest a solution based on that, I am open to it:) I was just frustrated because I spent a good bit of time trying to figure it out, but I'm not super familiar w it and the documentation is pretty hard to understand (esp b/c datetime objects, blah blah)
There is an obvious problem in this section:
duration = end - start
if duration >= 0:
duration = duration
elif duration < 0:
duration = -1*duration
If your start point is 22:00:00 and end point is 21:00:00 your duration will be 1 hour instead of 23 hours.
I need to check how many seconds are lef to the nearest HH:MM time in Python (in 24 hour format). For example, now is 10:00 - I need to check 16:30 same day.
If its 18:00 I need to check secods left to the 16:30 next day end so on.
You probably want to use the datetime module, timeldelta is your friend here:
import datetime
def cal_delta_to(hour, minute):
now = datetime.datetime.now()
target = datetime.datetime(*now.timetuple()[0:3], hour=16, minute=30)
if target < now: # if the target is before now, add one day
target += datetime.timedelta(days=1)
diff = now - target
return diff.seconds
Start with simple steps. Programming is usually about breaking down tasks like these into steps.
Get current time. Get next 16:30. Subtract.
# use datetime
from datetime import datetime, timedelta
# get current time
curr = datetime.now()
# create object of nearest 16:30
nearest = datetime(curr.year, curr.month, curr.day, 16, 30)
# stupidly check if it's indeed the next nearest
if nearest < curr:
nearest += timedelta(days=1)
# get diff in seconds
print (nearest - curr).seconds
If your format is ensured, you can easily calculate the seconds of the day:
def seconds_of_day(hhmm):
return int(hhmm[:2])*3600 + int(hhmm[3:])*60
Having done this the comparison is straightforward:
t1 = seconds_of_day('16:30')
t2 = seconds_of_day('10:00')
#t2 = seconds_of_day('18:01')
diff = 86400-t2+t1 if t1<t2 else t1-t2
Use datetime:
import datetime
func = lambda s: datetime.datetime.strptime(s, '%H:%M')
seconds = (func(s2)-func(s1)).seconds
You can always get what you want, even in the special 'next day' cases, like in case1 below;
# case1: now is '09:30', check seconds left to the 09:29 next day
>>> (func('09:29')-func('09:30')).seconds
86340
# case2: now is '09:30', check 10:30 the same day
>>> (func('10:30')-func('09:30')).seconds
3600
I want to control devices (module Raspberry Pi) in a certain time period. I make a PHP web to config time value in database mysql. Then I get time from database to compare with time in system (real time clock). If system time is in between time in mysql => led on.
Here is my table(name: time) in mysql:
start_time stop_time
07:00:00 (Type: time) 08:00:00 (Type:time)
And here is my code control device:
import MySQLdb
import RPi.GPIO as GPIO
from datetime import date
import time
db_local = MySQLdb.connect("localhost","root","root","luan_van")
with db_local:
cur = db_local.cursor(MySQLdb.cursors.DictCursor)
cur.execute("SELECT * FROM time")
rows = cur.fetchall()
start = 0
stop = 0
for row in rows:
start = row['start_time']
stop = row ['stop_time']
tg = strftime("%H:%M:%S", time.localtime())
if( start < tg < stop):
GPIO.output(12, True)
It error "can't compare datetime.timedelta to str".
How can I get system time value format "H:M:S"?
Thank for help.
Your start and stop objects are datetime.timedelta objects; these model time durations, not the time of day. You have two options here:
Produce another timedelta to represent the current time, as a delta since midnight
Convert the start and stop values to actual time-of-day values
You can produce a timedelta for 'now' with:
import datetime
midnight = datetime.datetime.combine(datetime.date.today(), datetime.time.min)
time_since_midnight = datetime.datetime.now() - midnight
then compare that with your start and stop:
if start < time_since_midnight < stop:
In the other direction, converting the start and stop timedeltas to datetime.datetime objects means you need to add them to the midnight object:
import datetime
midnight = datetime.datetime.combine(datetime.date.today(), datetime.time.min)
now = datetime.datetime.now()
if (midnight + start) < now < (midnight + stop):
A variation on the latter could be to just use the .time() components and ignore the date portion, but since you already are basing all dates on 'today' that won't make a difference here.