每小时运行一次脚本 - 偏离几秒/分钟

Running script every hour - deviating by few second/minutes

提问人:Prmake 提问时间:10/28/2022 更新时间:10/29/2022 访问量:80

问:

我每小时运行一个脚本(计时器为 3600 秒)。但是每次运行时,我的导出文件(我的脚本的结果)的时间戳都晚于前一个。几乎不可能找到最佳位置并坚持大约相同的出口时间。有什么建议可以有一个更稳定、更可靠的计时器吗?

法典:

import pandas as pd
from datetime import datetime as dt
import schedule
import time

def export():
    df = pd.read_excel("filepath", sheet_name='Import Data')
    now =dt.now()
    dt_string = now.strftime("%Y%m%d %H%M%S")
    df["Minute"] = now.minute
    df["Hour"] = now.hour
    df["Day"] = now.day
    df["Month"] = now.month
    df["Year"] = now.year
    df.to_excel("filepath" + dt_string + ".xlsx", sheet_name='Export Data')

schedule.every(3600).seconds.do(export)

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

评论

0赞 Mehmaam 10/28/2022
老实说,我不明白你的问题。如果你现在可以使用。关键字可以转换当前时间

答:

2赞 Tamas K 10/28/2022 #1

解决此问题的方法是根据实际时钟调整运行时间。我所说的实际时钟,是指例如UTC时间,或者您系统上的任何时间。时区并不重要。重要的是根据时间进行调度,而不是根据上次运行以来经过的时间。

测量经过时间的问题在于,您需要考虑进行测量所需的时间,并且可能还有其他因素会导致延迟。

解决方案 1

这是我最初的想法,在我意识到日程安排库也可以做到这一点之前。 您可能想直接跳到下面的 Soluition 2,这更简单。

下面是一个示例代码。它每 5 秒运行一个方法。这样,延迟不会随时间而变化,时间将保持不变。

您需要根据需要进行调整。你可以修改它,让它每小时运行一次,而不是每 5 秒运行一次,想法是一样的。

示例代码:

import time
from datetime import datetime as dt
import threading
from threading import Event

def export():
    print("Do something every 5 seconds.")


run_once = Event()
run_once.clear()


def run_method(method_to_run):
    while 1:
        run_once.wait()
        run_once.clear()
        method_to_run()

thread = threading.Thread(target=run_method, args=(export,))
thread.start()

last_run = 0

while 1:
    when_to_run = int(dt.now().second / 5)
    if when_to_run > last_run:
        last_run = when_to_run
        run_once.set()
    elif when_to_run < last_run:
        last_run = when_to_run
    time.sleep(1)

编辑 1:如果要每小时运行一次任务,则需要修改上面示例中的以下行:

    # when_to_run = int(dt.now().second / 5)
    when_to_run = int(dt.now().hour)

编辑 2:添加解决方案 2。

解决方案 2

使用库的方法。(感谢@itprorh66的评论。schedule.at()

文档:https://schedule.readthedocs.io/en/stable/reference.html#schedule.Job.at

示例代码:

import time
import schedule


def export():
    print("Do something every 5 seconds.")


schedule.every().hour.at(":00").do(export)

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

评论

2赞 itprorh66 10/28/2022
如何利用日程库?
0赞 Tamas K 10/28/2022
@itprorh66 感谢您的评论,我没有意识到也可以做到这一点。我编辑了我的答案。