Start and stop a Python script at a specific time - python

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.

Related

How to find the amount of minutes between the current time and a future time of the same day in python

I'm trying to make a program that tells me how long there is (in minutes) until a certain time of day in the future. I've been trying to write working code all night, but I just can't wrap my head around strftime, timedelta and datetime. I'm quite new to python, and being able to do this would be quite useful to my day-to-day life; Can someone help me out?
from datetime import datetime
def minutes_until(hour, minute):
#get the current time
now = datetime.now()
#get the current hour
current_hour = now.hour
#get the current minute
current_minute = now.minute
#get the current second
current_second = now.second
#get the current microsecond
current_microsecond = now.microsecond
#get the time until the specified hour
time_until_hour = hour - current_hour
#get the time until the specified minute
time_until_minute = minute - current_minute
#get the time until the specified second
time_until_second = 60 - current_second
#get the time until the specified microsecond
time_until_microsecond = 1000000 - current_microsecond
#get the total time until the specified time
total_time = time_until_hour * 3600 + time_until_minute * 60 + time_until_second + time_until_microsecond / 1000000
#get the total time in minutes
total_time_in_minutes = total_time / 60
#return the total time in minutes
return total_time_in_minutes
print(minutes_until(15, 0)) #time now is 2 PM, how long until 15:00 (3PM)? = 60 minutes
You can try:
from datetime import datetime
target = '2023-01-01 00:00:00'
t = datetime.strptime(target, '%Y-%m-%d %H:%M:%S')
now = datetime.now()
print(f'{(t-now).total_seconds()/60:.0f} minutes')
output: 104445 minutes

why is not the result 00:00:XX?

i expected like 00:00:0X but 09:00:0X came out how can i do to make 00:00:0X
import time
start = input("Enter를 누르면 타이머를 시작합니다.")
begin = time.time()
while True:
time.sleep(1)
count = time.time()
result = time.localtime(count - begin)
print(count - begin)
print(time.strftime('%I:%M:%S', result))
result:
1.0102884769439697
09:00:01
2.0233511924743652
09:00:02
3.0368154048919678
time.time() will give you the number of seconds since 1.1.1970 in UTC.
So begin is a huge number and count will also be a huge number + about 1. Subtracting those will give about 1.
If you pass this to time.time() you'll get 1.1.1970 plus 1 second. Converting to local time (time.localtime()) will give you whatever timezone offset you are. Obviously +9 hours.
What you probably wanted is time.gmtime() and output in 24 hour format. This will work...
import time
start = input("Enter를 누르면 타이머를 시작합니다.")
begin = time.time()
while True:
time.sleep(1)
count = time.time()
result = time.gmtime(count - begin)
print(count - begin)
print(time.strftime('%H:%M:%S', result))
but it is semantically incorrect. If you subtract 2 dates, the result is a timespan, not a date. What is the difference?
If someone asks, how old you are, you have a look at the current year and you subtract the year of your birth. Then you say "I'm 25 years old". You don't add 1.1.1970 and say "I'm 1995 years old".
So the following is semantically much better:
import time
from datetime import timedelta
start = input("Enter를 누르면 타이머를 시작합니다.")
begin = time.time()
while True:
time.sleep(1)
count = time.time()
timespan = timedelta(seconds=count - begin)
print(timespan)
It shows 09:00:00 because you're in the UTC+9 timezone. For example, I'm in UTC+1 (France) and it shows 01:00:00 for me. Therefore, your code will have different outputs depending on where you run it.
To remove this timezone constraint, simply use datetime.timedelta:
begin = time.time()
while True:
time.sleep(1)
count = time.time()
print(datetime.timedelta(seconds=round(count - begin)))
Output:
0:00:01
0:00:02
0:00:03
0:00:04
0:00:05

Real Time Clock(RTC) in Python

I am a beginner in Python. I am wondering about does Python has Real Time Clock which is giving us exactly year, month, day, hour, min, and second?
Thank you for your help!
For Date Time operations in python you need to import datetime library.There different functions related to date formatting, getting current date and time etc.. Refer this documentation
import datetime
now = datetime.datetime.now()
print ("Current date and time : ")
print (now.strftime("%Y-%m-%d %H:%M:%S"))
Hope the above code will do your job ...
datetime.now()
Thats it.It gives the current date and time upto microseconds.
Use as you want.
Setting an alarm after 2 days.
alarm_time = date.today() + timedelta(days = 2) #set alarm time 2day after today
while(date.today()!=alarm_time): #run loop till datetoday is not alarm_time
time.sleep(60*60) #wait for an hour then recheck time
#do here anything you want to do when alarm time has reached#
you can try this:
temp.year, temp.month, temp.day,temp.hour,temp.minute,temp.second would give your desire values separately
from datetime import datetime
temp = datetime.now()
timee = "{:04d}{:02d}{:02d} {:02d}:{:02d}:{:02d}".format(temp.year, temp.month, temp.day,temp.hour,temp.minute,temp.second)

How do I stop a program from running more than once a day?

I want to prevent my program from running and accepting input more than once a calendar day. Is there a way to do this?
I tried importing the date at the end of my code and storing it in variable and then importing the date at the start of the code and comparing them but of course, the variable at the end of the code is not defined when you run the code for the first time.
import datetime
new_time = str(datetime.datetime.now())
new_time = new_time[8:10]
new_time = int(new_time)
while new_time == last_time:
print("Please wait until tomorrow before entering a new value")
last_time = str(datetime.datetime.now())
last_time = last_time[8:10]
last_time = int(last_time)
With this approach, it works except for the first time when the variable last_time is not defined
By appending the current date into a file, you can compare the calendar day difference.
Code:
import datetime
new_day = int(datetime.datetime.now().strftime("%d"))
last_day = 0
with open("last_time.txt", "r") as f:
lines = f.read().splitlines()
last_day = lines[-1]
if new_day == int(last_day):
print("Please wait until tomorrow before entering a new value")
with open("last_day.txt", "a+") as f:
last_day = datetime.datetime.now().strftime("%d")
f.write(last_day)
Explanation:
1. Create a text file(last_time.txt) and give the default day as when you are running the script for first time(as today(24))
2. get the new_day as day from datetime.now() and convert into an integer.
3. By default keeping the last_day=0 or you can give the current date for first time
4. Reading the last time from the last line of the file
5. If new_day and last_day are equal, then print the message to the user.
6. Fetch the current day as last_day and write to a file in append mode.
File O/p:
23
24
O/P:
Please wait until tomorrow before entering a new value

Seconds left to HH:MM

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

Categories

Resources