计算从现在到特定时间点的时间

Posted

技术标签:

【中文标题】计算从现在到特定时间点的时间【英文标题】:Calculate time between now and a specific timepoint 【发布时间】:2021-09-20 10:05:12 【问题描述】:

我正在尝试用 python 编写一个程序,每天在特定时间开始执行一项任务。因为当电脑打开时它会一直运行,所以我想让它尽可能轻。因此,我不想永远检查时间,而是想检查一次时间并计算在正确的时间之前要睡多少秒。

【问题讨论】:

如果在 *nix 系统上,也许考虑将任务安排为 cron 作业。 【参考方案1】:

您选择何种机制来提醒您并运行脚本取决于您,但就计算时间而言,您可以使用timedelta。比如;

from datetime import datetime, timedelta
now = datetime.now()
tomorrow = now + timedelta(1)

所以您现在可以想象,您所要做的就是将结果转换为您想要的任何格式。 (秒、分、小时等)

【讨论】:

【参考方案2】:

你可以

import time

startTime = time.time()
time.sleep(3600) # one hour from current time
if time.time() - startTime > 3600:
 yourTask()

from datetime import datetime, timedelta
import time
currTime = datetime.now()
futureTime = currTime+timedelta(hours = 2) # 2 hours from now, you also can specify days
time.sleep(futureTime-currTime)
#OR Just
time.sleep(timedelta(hours = 2))
yourTask()

这就是python中sleep和time函数的大致思路

【讨论】:

【参考方案3】:

要每天在同一时间运行相同的功能,您可以使用下面的 sched.scheduler 类或不需要该类的解决方案,我稍后会展示并且更简单一些:

请参阅 Python 事件调度程序模块 sched 的文档(部分):

sched.scheduler(timefunc=time.monotonic, delayfunc=time.sleep)

调度程序类定义了一个用于调度事件的通用接口。它需要两个函数来实际处理“外部世界”——timefunc 应该可以不带参数调用,并返回一个数字(“时间”,任何单位)。 delayfunc 函数应该可以用一个参数调用,与 timefunc 的输出兼容,并且应该延迟那么多时间单位。在每个事件运行后,也会使用参数 0 调用 delayfunc,以允许其他线程有机会在多线程应用程序中运行。

scheduler.enterabs(时间、优先级、动作、参数=()、kwargs=)

安排新活动。 time 参数应该是与传递给构造函数的 timefunc 函数的返回值兼容的数字类型。安排在同一时间的事件将按其优先级顺序执行。数字越小表示优先级越高。

import datetime
import sched
import time

# number of seconds in:
HOURS_SECONDS = 3600
MINUTES_SECONDS = 60

def my_time_func():
    date_and_time = datetime.datetime.now()
    # convert time component to absolute seconds since midnight:
    return date_and_time.hour * HOURS_SECONDS + date_and_time.minute * MINUTES_SECONDS  + date_and_time.second

def my_sleep_func(t):
    #print('sleeping', t, 'seconds')
    time.sleep(t)

def do_work():
    print('I am working!')

s = sched.scheduler(timefunc=my_time_func, delayfunc=my_sleep_func)
# schedule something to begin every day at (24-hour clock:)
EVENT_HOURS=9
EVENT_MINUTES=35
EVENT_SECONDS=0
first_time = True
while True:
    now = datetime.datetime.now()
    next_event_dt = datetime.datetime(now.year, now.month, now.day, hour=EVENT_HOURS, minute=EVENT_MINUTES, second=EVENT_SECONDS)
    schedule_event = True
    if first_time:
        first_time = False
        # maybe too late for initial schedule day:
        if next_event_dt < now:
            schedule_event = False
    if schedule_event:
        event = s.enterabs(time=EVENT_HOURS * HOURS_SECONDS + EVENT_MINUTES * MINUTES_SECONDS + EVENT_SECONDS, priority=1, action=do_work)
        s.run()
    delta = next_event_dt + datetime.timedelta(days=1) - datetime.datetime.now()
    my_sleep_func(delta.total_seconds())

如果你不想使用sched.scheduler 类:

import datetime
import time

# number of seconds in:
HOURS_SECONDS = 3600
MINUTES_SECONDS = 60

def my_sleep_func(t):
    #print('sleeping', t, 'seconds')
    time.sleep(t)

def do_work():
    print('I am working!')

# schedule something to begin every day at (24-hour clock:)
EVENT_HOURS=10
EVENT_MINUTES=30
EVENT_SECONDS=0
first_time = True
while True:
    now = datetime.datetime.now()
    next_event_dt = datetime.datetime(now.year, now.month, now.day, hour=EVENT_HOURS, minute=EVENT_MINUTES, second=EVENT_SECONDS)
    schedule_event = True
    if first_time:
        first_time = False
        # maybe too late for initial schedule day:
        if next_event_dt < now:
            schedule_event = False
    if schedule_event:
        delta = next_event_dt - datetime.datetime.now()
        t = delta.total_seconds()
        if t > 0:
            my_sleep_func(t)
        do_work()
    delta = next_event_dt + datetime.timedelta(days=1) - datetime.datetime.now()
    my_sleep_func(delta.total_seconds())

如果你想确保你的工作函数在第一天运行,即使你的程序在事件的开始时间之后开始,然后将你的循环更改为以下(如果你使用sched.scheduler类):

while True:
    now = datetime.datetime.now()
    next_event_dt = datetime.datetime(now.year, now.month, now.day, hour=EVENT_HOURS, minute=EVENT_MINUTES, second=EVENT_SECONDS)
    delta = next_event_dt - datetime.datetime.now()
    t = delta.total_seconds()
    if t > 0:
        my_sleep_func(t)
    do_work()
    delta = next_event_dt + datetime.timedelta(days=1) - datetime.datetime.now()
    my_sleep_func(delta.total_seconds())

不用说(但我还是会说),my_sleep_func 只是 time.sleep 的替代品,如果您取消注释掉 print 语句,则可以打印出一些诊断信息。

【讨论】:

以上是关于计算从现在到特定时间点的时间的主要内容,如果未能解决你的问题,请参考以下文章

如何计算图片内部的特定距离?

如何计算交叉跟踪误差(GPS/核心位置)

Binance的24小时百分比变化是如何计算的

如何获得特定点的核密度估计值?

如何计算具有特定中心的正方形多边形?

从 vb.net 中的访问中计算特定记录