我一直在建设一个错误记录的应用程序和最近的是后一种方法的准确时间戳进入的数据。当我准确地说我的意思是每个时间戳应该准确,相对于每一个其他(否需要同步到原子时钟或什么喜欢那)。

我一直在使用日期时间。now()作为第一个刺伤的,但这不是完美的:

>>> for i in range(0,1000):
...     datetime.datetime.now()
...
datetime.datetime(2008, 10, 1, 13, 17, 27, 562000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 562000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 562000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 562000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 578000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 578000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 578000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 578000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 578000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 609000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 609000)
datetime.datetime(2008, 10, 1, 13, 17, 27, 609000)
etc.

变化之间的时钟为第一第二的样品,是这样的:

uSecs    difference
562000  
578000  16000
609000  31000
625000  16000
640000  15000
656000  16000
687000  31000
703000  16000
718000  15000
750000  32000
765000  15000
781000  16000
796000  15000
828000  32000
843000  15000
859000  16000
890000  31000
906000  16000
921000  15000
937000  16000
968000  31000
984000  16000

因此它看起来像定时数据的仅仅是更新,每~15-32ms在我的机器。问题是当我们来分析数据,因为排序比其他的东西的时间戳然后按时间戳再次可以离开的数据的顺序错误(按时间顺序).这将是很好有时间邮票的准确指出,任何呼叫的时间戳发电机提供了一个独特的时间戳。

我已经在考虑一些方法涉及使用一个时间。时钟()电话加入到开始日期时间,但是将一种解决方案,将精确地跨越线在同一台机器上。任何建议将非常感激地接收。

有帮助吗?

解决方案

你不可能获得足够细粒度的控制,你可以完全消除这种可能性 重复时间戳 - 您需要的分辨率小于生成日期时间对象所需的时间。您可以采取其他几种方法来处理它:

  1. 处理它。保留您的时间戳不是唯一的,但依赖于python的排序稳定来处理重新排序问题。在时间戳首先上排序,然后其他东西将保留时间戳排序 - 您必须小心每次始终从时间戳排序列表开始,而不是在同一列表上进行多种排序。

  2. 附加您自己的值以强制执行唯一性。例如。包括递增的整数值作为键的一部分,或仅在时间戳不同时附加这样的值。例如

  3. 以下内容将保证唯一的时间戳值:

        class TimeStamper(object):
            def __init__(self):
                self.lock = threading.Lock()
                self.prev = None
                self.count = 0
    
             def getTimestamp(self):
                 with self.lock:
                     ts = str(datetime.now())
                     if ts == self.prev:
                         ts +='.%04d' % self.count
                         self.count += 1
                     else:
                         self.prev = ts
                         self.count = 1
                 return ts
    

    对于多个进程(而不是线程),它会变得有点棘手。

其他提示

time.clock()仅测量Windows上的挂钟时间。在其他系统上,time.clock()实际测量CPU时间。在那些系统上,time.time()更适合于挂钟时间,并且它具有Python可以管理的高分辨率 - 这与操作系统可以管理的一样高;通常使用gettimeofday(3)(微秒分辨率)或ftime(3)(毫秒分辨率。)其他操作系统限制实际上使真正的分辨率高出许多。 datetime.datetime.now()使用time.time(),所以time.time()直接不会更好。

对于记录,如果我在循环中使用datetime.datetime.now(),我会看到1/10000秒的分辨率。通过查看您的数据,您可以获得更多,更粗糙的分辨率。我不确定Python是否可以做任何事情,尽管你可以说服操作系统通过其他方式做得更好。

我似乎记得在Windows上,time.clock()实际上(稍微)比time.time()更准确,但它自第一次调用time.clock()以来测量wallclock,所以你必须记住首先“初始化”它。

谢谢大家的贡献 - 他们都非常有用。 Brian的答案似乎与我最终的答案最接近(即处理它但使用一种独特的标识符 - 见下文)所以我接受了他的答案。我设法将所有各种数据接收器合并到一个线程中,现在使用我的新 AccurrateTimeStamp 类来完成时间戳。只要时间戳是第一个使用时钟的东西,我所做的就是工作。

正如S.Lott规定的那样,如果没有实时操作系统,它们将永远不会完美无缺。我真的只想要一些可以让我看到相对于每个传入的数据块的东西,当收到的东西时,我在下面得到的东西都会很好。

再次感谢大家!

import time

class AccurateTimeStamp():
    """
    A simple class to provide a very accurate means of time stamping some data
    """

    # Do the class-wide initial time stamp to synchronise calls to 
    # time.clock() to a single time stamp
    initialTimeStamp = time.time()+ time.clock()

    def __init__(self):
        """
        Constructor for the AccurateTimeStamp class.
        This makes a stamp based on the current time which should be more 
        accurate than anything you can get out of time.time().
        NOTE: This time stamp will only work if nothing has called clock() in
        this instance of the Python interpreter.
        """
        # Get the time since the first of call to time.clock()
        offset = time.clock()

        # Get the current (accurate) time
        currentTime = AccurateTimeStamp.initialTimeStamp+offset

        # Split the time into whole seconds and the portion after the fraction 
        self.accurateSeconds = int(currentTime)
        self.accuratePastSecond = currentTime - self.accurateSeconds


def GetAccurateTimeStampString(timestamp):
    """
    Function to produce a timestamp of the form "13:48:01.87123" representing 
    the time stamp 'timestamp'
    """
    # Get a struct_time representing the number of whole seconds since the 
    # epoch that we can use to format the time stamp
    wholeSecondsInTimeStamp = time.localtime(timestamp.accurateSeconds)

    # Convert the whole seconds and whatever fraction of a second comes after
    # into a couple of strings 
    wholeSecondsString = time.strftime("%H:%M:%S", wholeSecondsInTimeStamp)
    fractionAfterSecondString = str(int(timestamp.accuratePastSecond*1000000))

    # Return our shiny new accurate time stamp   
    return wholeSecondsString+"."+fractionAfterSecondString


if __name__ == '__main__':
    for i in range(0,500):
        timestamp = AccurateTimeStamp()
        print GetAccurateTimeStampString(timestamp)

“时间戳应相对于彼此准确”

为何时间?为什么不是序列号?如果它是客户端 - 服务器应用程序的任何客户端,则网络延迟会使时间戳变得随机。

您是否匹配某些外部信息来源?说一个其他应用程序的日志?同样,如果有网络,那些时间也不会太近。

如果您必须在不同的应用程序之间匹配,请考虑传递GUID,以便两个应用程序都记录GUID值。无论时间差异如何,你都可以绝对确定它们是否匹配。

如果您希望 relative 订单完全正确,那么您的记录器可能会按照收到的顺序为每条消息分配序列号。

这是关于Python计时准确性的一个主题:

Python - time.clock()与time.time() - 准确度?

几年过去,因为该问题已经提问和回答,这已得到处理,至少对于CPython。使用下脚本两windows7资64位和Windows服务器2008年R2,我得到了同样的结果:

  • datetime.now() 给出了一个决议1毫秒和抖动小于1毫秒
  • time.clock() 给出了一个分辨率好于1和抖动远远小于1毫秒

脚本:

import time
import datetime

t1_0 = time.clock()
t2_0 = datetime.datetime.now()

with open('output.csv', 'w') as f:
    for i in xrange(100000):
        t1 = time.clock()
        t2 = datetime.datetime.now()
        td1 = t1-t1_0
        td2 = (t2-t2_0).total_seconds()
        f.write('%.6f,%.6f\n' % (td1, td2))

结果可视化:enter image description here

我想感谢J. Cage的最后一篇文章。

对于我的工作,“合理”跨流程和平台的事件发生时间至关重要。显然有很多地方可以歪斜(时钟漂移,上下文切换等),但是我认为这种精确的时序解决方案有助于确保记录的时间戳足够精确,以便查看其他错误来源。

也就是说,我想知道的一些细节在 MicroSeconds很重要。例如,我认为time.clock()最终会换行。我认为为了长期运行这个过程,你可能需要处理它。

如果你想在Python中使用microsecond- 分辨率(非准确性)时间戳,在 Windows,中你可以使用Windows的QPC计时器,如我在这里的回答所示:如何在Python中获得毫秒和微秒分辨率的时间戳。我还不确定如何在Linux中这样做,所以如果有人知道,请在上面的链接中发表评论或回答。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top