在确切的时间调用函数

时间:2013-03-15 06:54:57

标签: time python-2.7

我只是在学习Python。出于某种奇怪的冲动,我试图创建一个decimal clock。此十进制时钟将日期分为每天10小时,每小时100分钟,每分钟100秒。十进制日有100,000秒; 86,000在“古老”的时间。每1秒的古老时间等于~1.157秒的新的,改进的十进制时间(假设我已经得到了一点点数学正确。)

我遇到的问题是,为了让时钟准确地按顺序勾选小数秒,我需要一个函数来尽可能准确地每1.157秒触发一次。我有一个调用函数DeciTimeCaller,它无限循环,调用decimaltime.time_to_string方法,该方法从古代时间转换为十进制时间,并以十进制小时打印时间:min:sec。然后,调用函数将休眠time.sleep(1.157),并完成所有操作。

但是由于后台进程优先(我假设),打印时间会在这里和那里跳过几秒钟。

例如,这里的输出大约是20秒:

0:85:92
0:85:93
0:85:95
0:85:96
0:85:97
0:85:99
0:86:00
0:86:01
0:86:03
0:86:04
0:86:05
0:86:07
0:86:08

我认识到Python和Linux不构成实时系统,我在其他线程中尝试了一些建议,例如: Sleep for exact time in python,但没有成功。但我认为可能有某种方法来捏造这个。

所以问题是:我可以让这个时钟像钟表一样运行吗?

我的代码如下。有几点要注意:我导入了线程模块,因为我试图使用事件,但我目前没有使用它。我使用十进制模块,因为我认为转换中的浮点值的精度可能存在问题。似乎没有任何区别。我还有timeit模块和一些注释代码,我一直在试图调用它们。

import time
import datetime as dt
import decimal
import threading
import timeit

class decimaltime:
  """ Presents the time of day in Decimal Time 
      10 Hours/day
      100 minutes/hour
      100 seconds/minute
  """
  def time(self, archaic_seconds = 0):
    if archaic_seconds == 0:
      now = decimal.Decimal(dt.datetime.now().strftime('%s.%f'))
      midnight = decimal.Decimal(dt.date.today().strftime('%s.%f'))
      archaic_seconds_from_midnight = decimal.Decimal(now - midnight)
    else:
      archaic_seconds_from_midnight = decimal.Decimal(archaic_seconds)
    return archaic_seconds_from_midnight * decimal.Decimal('1.157')

  def time_to_string(self, decimal_seconds = 0):
    if decimal_seconds == 0:  
      seconds_from_midnight = self.time() 
    else:
      seconds_from_midnight =  decimal.Decimal(decimal_seconds)
    decimal_hour = seconds_from_midnight / 10000
    decimal_minute = (seconds_from_midnight % 10000) / 100
    decimal_second = seconds_from_midnight % 100
    time_string = "%(hour)01d:%(minute)02d:%(second)02d" % {"hour": decimal_hour, "minute": decimal_minute, "second": decimal_second}
    print time_string
    # return time_string

def DeciTimeCaller():
  decitime = decimaltime()
  # t = timeit.Timer(lambda: decitime.time_to_string())
  while True:
    # print t.timeit(1)
    decitime.time_to_string()
    time.sleep(1.157)

DeciTimeCaller()

更新

根据Thomas的建议,我修改了代码,每隔1/10秒检查一次小数时间。如果十进制时间已更改,我打印出时间。这就像发条一样,这正是我所寻找的。

这是修订后的DeciTimeCaller函数:

def DeciTimeCaller():
  decitime = decimaltime()
  old_time = decitime.time_to_string()
  while True:
    new_time = decitime.time_to_string()
    if (new_time != old_time): 
      print new_time
      old_time = new_time
    time.sleep(.1667)

1 个答案:

答案 0 :(得分:2)

以精确的频率运行函数非常困难。

您可以创建一个函数,将当前系统时间转换为十进制时间30次/秒。这样你的时间总是正确的,你永远不会失去同步。