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

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

【问题讨论】:

  • 如果在 *nix 系统上,也许考虑将任务安排为 cron 作业。

标签: python time sleep


【解决方案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 语句,则可以打印出一些诊断信息。

      【讨论】:

        猜你喜欢
        • 2016-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-16
        • 1970-01-01
        相关资源
        最近更新 更多