【问题标题】:Sleep till next 15 minute hourly interval (00:00, 00:15, 00:30, 00:45)睡眠到下一个 15 分钟每小时间隔 (00:00, 00:15, 00:30, 00:45)
【发布时间】:2017-09-30 19:30:11
【问题描述】:

我需要我的脚本休眠到下一个每小时 15 分钟的间隔,例如整点、一刻钟、半点钟和一刻钟。

它看起来像这样

While True:
    //do something
    sleepy_time = //calculate time to next interval
    time.sleep(sleepy_time)

您可以编写一系列 if 语句来检查当前分钟数是多少,然后执行“if current

编辑:基于@martineau 的回答,这是我使用的代码。

import datetime, time

shouldRun = True
if datetime.datetime.now().minute not in {0, 15, 30, 45}:
    shouldRun = False
# Synchronize with the next quarter hour.
while True:
    if shouldRun == False:
        current_time = datetime.datetime.now()
        seconds = 60 - current_time.second
        minutes = current_time.minute + 1
        snooze = ((15 - minutes%15) * 60) + seconds
        print('minutes:', minutes, 'seconds', seconds, ' sleep({}):'.format(snooze))
        localtime = time.asctime( time.localtime(time.time()))
        print("sleeping at " + localtime)
        time.sleep(snooze)  # Sleep until next quarter hour.
        shouldRun = True
    else:
        localtime = time.asctime( time.localtime(time.time()))
        print("STUFF HAPPENS AT " + localtime)
        shouldRun = False

他的答案和这之间的区别在于,这个 else 块每个间隔只运行一次,然后如果分钟仍然在 0、15、30、45 间隔上,则计算额外的秒数以添加到睡眠时间,直到下一个间隔。

【问题讨论】:

  • @AndreyMuzalevsky 我不希望它每 15 分钟运行一次。我希望它在整点、一刻钟、半点钟和一刻钟时运行。如果脚本在 17:10 开始,则每 15 分钟运行一次是行不通的,因为下一次运行要等到 17:25 而不是 17:15。
  • crontab 会为你工作吗?
  • @AndreyMuzalevsky 不幸的是没有。托管服务器的公司已限制作业,因此您不能让它们每 15 分钟运行一次。乔的回答似乎奏效了
  • 如果您的主机无法为您提供运行作业的能力 - 您也可能陷入最大执行时间限制...

标签: python python-2.7 time


【解决方案1】:

你可以使用datetime...

datetime.datetime.now() 的调用将返回一个datetime,您可以通过.minute 获取当前的minute 通过hour

一旦我们将minutes 的数量超过了hour,我们就可以这样做modulo 15 以获取minutes 的数量到15 的下一个区间。

从这里,只需使用minutes60 (每分钟60 秒)调用time.sleep()

此代码可能类似于:

import datetime, time

minutesToSleep = 15 - datetime.datetime.now().minute % 15
time.sleep(minutesToSleep * 60)
print("time is currently at an interval of 15!")

【讨论】:

  • 会根据脚本的开始时间给出 15 分钟的间隔,还是根据小时给出 15 分钟的间隔。例如如果脚本在 17:10 开始,那么下一个间隔将是 17:25 而不是 17:15?
  • 我不认为这是正确的。 2:02 它只会睡 2 分钟。
  • 完美!出于某种原因,我认为你不能对时间数字进行取模,因为它们是以 60 为增量而不是以 10 为基数。一旦计时器允许,我会接受它。
  • 编辑到15 - datetime.datetime.now().minute % 15后我同意。
  • @PhilipBlondé 对此感到抱歉!
【解决方案2】:

time.sleep(15*60 - time.time() % (15*60))

15*60 是每 15 分钟的秒数。

time.time() % (15*60) 将是当前 15 分钟帧中经过的秒数(因为根据定义,时间 0 是 00:00)。它在 XX:00、XX:15、XX:30、XX:45 时从 0 增长到 15*60-1(实际上,15*60-0.(0)1 — 取决于时间测量的精度),然后开始增长再次从 0 开始。

15*60 - time.time() % (15*60) 是距离 15 分钟帧结束的秒数。通过基本的数学计算,它从 15*60 减少到 0。

所以,你需要睡那么多秒。

但是,请记住,睡眠不会非常精确。处理time.time()之间的内部指令需要一些时间,而time.sleep()实际上是在系统级别调用的。可能是一秒的纳米分数。但在大多数情况下是可以接受的。

另外,请记住,time.sleep() 并不总是在被要求睡眠的时间里睡眠。它可以被发送到进程的信号唤醒(例如,SIGALRM、SIGUSR1、SIGUSR2 等)。所以,除了睡觉,还要检查time.sleep()之后是否到了正确的时间,如果没有,就再睡觉。

【讨论】:

    【解决方案3】:

    我认为@Joe Iddon 的回答不太正确,尽管它很接近。试试这个(注意我注释掉了我不想运行的行并添加了一个for循环来测试minute的所有可能值):

    import datetime, time
    
    # Synchronize with the next quarter hour.
    #minutes = datetime.datetime.now().minute
    for minutes in range(0, 59):
        if minutes not in {0, 15, 30, 45}:
            snooze = 15 - minutes%15
            print('minutes:', minutes, ' sleep({}):'.format(snooze * 60))
            #time.sleep(snooze)  # Sleep until next quarter hour.
        else:
            print('minutes:', minutes, ' no sleep')
    

    【讨论】:

    • 如果snooze = 15 - minutes%15 行不应该是snooze = (15 - minutes%15) * 60,因为此时您在打印行中将其乘以 60,但是如果您取消注释睡眠行以实际睡眠,它只会以分钟不是以秒为单位的差异。除此之外,我看不出这与乔之间的区别,除了他没有测试代码,他将当前分钟的获取和模数组合到一个操作中?
    • jskrwyk:测试循环中的代码没有针对速度进行优化。 @Joe 和我之间的显着功能差异是,如果当前时间恰好落在一刻钟中的一个,那么睡眠时间是多少。
    • jskrwyk:简单来说。如果当前时间的分钟正好在00153045 小时后,Joe 的技术将sleep() 15 分钟,而我的版本将完全跳过对sleep() 的调用,因为没有需要。
    • 我已经接受了答案,但最终我也对其进行了调整。我对其进行了更改,使其第一次不会在 0、15、30 和 45 分钟睡眠,但在完成它应该在这些间隔内完成的工作几秒钟后,它将允许代码运行睡眠内容,但是计算额外的秒数以将其四舍五入到 1、16、31、46 分钟。我已将用于问题的代码添加为编辑。
    【解决方案4】:
    import time
    
    L = 15*60
    
    while True:
        #do something
    
        #get current timestamp as an integer and round to the
        #nearest larger or equal multiple of 15*60 seconds, i.e., 15 minutes
        d = int(time.time())
    
        m = d%L        
        sleepy_time = 0 if m == 0 else (L - m)
    
        print(sleepy_time)
        time.sleep(sleepy_time)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      相关资源
      最近更新 更多