1

How would I run a task using just the date and time so that it runs only once but also is ran even if the exact time doesn't match because the program has been sleeping? I can do an if hour and if minute and if second but I'm sleeping between loops so it's likely not to see that exact time.

if (rtc.getHour() == 14):
    if (rtc.getMinutes() == 00):
        if (rtc.getSeconds() == 00):
Woodford
  • 3,746
  • 1
  • 15
  • 29
  • Change your code to while True: sleep 30 seconds; and then do this - Save your last run time in some file. Read this value as last_run_time, and if last_run_time is < today 14:00:00, and current time is >= 14:00:00, run the task and save current time to the file. – saurabheights Jan 31 '23 at 20:12
  • Add a `has_it_ran` flag and set it equal to `False` initially. Then, just use `if rtc.getHour() >= 14 and not has_it_ran` so if it's currently or past the scheduled time and it hasn't ran for the day, then run whatever task you want and then set the`has_it_ran` flag to True. – Michael Cao Jan 31 '23 at 20:13
  • What Michael Cao and I mentioned are same, but use file/db to save last run time. Rerunning the code/application will still preserve the app state and you wont accidentally run something more than once – saurabheights Jan 31 '23 at 20:16
  • I think if I only store the has_it_ran flag it could still run if compared to the hour. I think saurabheights has it were I need to store the time when it ran. – JohnnyPicnic Jan 31 '23 at 20:18
  • How do I get a last runtime on the first run? Not sure how to get the number stored if it's part of the comparison – JohnnyPicnic Jan 31 '23 at 20:23
  • @JohnnyPicnic - When your code runs for the first time and tries to load has_it_ran from say file app.json, the file wont exist. In that case, you set has_it_ran to false. When you run your code, you create this file and save has_it_ran there. However, if file exists, you just read has_it_ran from there. Furthermore, instead of saving has_it_ran, you can save the actual timestamp of the last run, which holds more information than a boolean variable. – saurabheights Feb 02 '23 at 09:27

1 Answers1

0
import schedule
import time

def your_task():
    # Your task
    print("Task executed")

schedule.every().day.at("14:00:00").do(your_task)

while True:
    schedule.run_pending()
    time.sleep(1)

This will run your task every day at 14:00:00, regardless of whether the program has been sleeping or not.

Edit:

import time
import json

def your_task():
    # Your task
    print("Task executed")

def run_pending_tasks():
    current_time = time.localtime()
    global last_execution_time
    last_execution_time_converted = time.strptime(last_execution_time, '%Y-%m-%d %H:%M:%S')
    current_date = time.strftime("%Y-%m-%d", current_time)
    if current_date in execution_data:
        if execution_data[current_date] == 1:
            return
        execution_data[current_date] += 1
    else:
        execution_data[current_date] = 1

    if (current_time.tm_hour >= 14 and current_time.tm_min >= 0 and current_time.tm_sec >= 0) and (time.mktime(current_time) - time.mktime(last_execution_time_converted)) >= 86400: # 86400 seconds in a day
        your_task()
        last_execution_time = time.strftime('%Y-%m-%d %H:%M:%S', current_time)
        
        with open('execution_data.json', 'w') as file:
            json.dump(execution_data, file)

last_execution_time = '2000-01-01 00:00:00'
try:
    with open('execution_data.json', 'r') as file:
        execution_data = json.load(file)
except FileNotFoundError:
    execution_data = {}

while True:
    run_pending_tasks()
    time.sleep(300)
111
  • 42
  • 1
  • 9