【问题标题】:How can I parse a time string containing milliseconds in it with python?如何使用 python 解析包含毫秒的时间字符串?
【发布时间】:2010-10-16 10:35:45
【问题描述】:

我可以使用 time.strptime

解析包含日期/时间的字符串
>>> import time
>>> time.strptime('30/03/09 16:31:32', '%d/%m/%y %H:%M:%S')
(2009, 3, 30, 16, 31, 32, 0, 89, -1)

如何解析包含毫秒的时间字符串?

>>> time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/_strptime.py", line 333, in strptime
    data_string[found.end():])
ValueError: unconverted data remains: .123

【问题讨论】:

    标签: python date time datetime-parsing


    【解决方案1】:

    Python 2.6 添加了一个新的 strftime/strptime 宏 %f。文档有点误导,因为它们只提到微秒,但 %f 实际上解析 任何 秒的小数部分,最多 6 位,这意味着它也适用于毫秒或甚至是厘秒或分秒。

    time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
    

    但是,time.struct_time 实际上并不存储毫秒/微秒。你最好使用datetime,像这样:

    >>> from datetime import datetime
    >>> a = datetime.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
    >>> a.microsecond
    123000
    

    如您所见,.123 被正确解释为 123 000 微秒。

    【讨论】:

    • 感谢docs.python.org/library/datetime.html:2.6 版中的新功能:时间和日期时间对象支持 %f 格式代码,该代码扩展为对象中的微秒数,在左侧补零到六个位置。
    • 哇,我可以告诉 Python 文档需要更新。 Docs for the time module 没有提及 %f
    • Python 文档,从 2.7.3 版开始,有点误导。对于 strptime,%f 实际上可以表示任意数量的小数位,而不仅仅是 6,正如人们可能期望的微秒。所以上面的代码会解析 32.123 秒并将其存储为 123,000µs,这正是我们想要的。
    • %f 中的数字在右边(不是左边!)补零到小数点后 6 位。 1被解析为100000,12被解析为120000,1234567产生ValueError: unconverted data remains: 7
    • 只是我的问题还是关于毫秒而不是微秒的问题?
    【解决方案2】:

    我知道这是一个较老的问题,但我仍在使用 Python 2.4.3,我需要找到一种将数据字符串转换为日期时间的更好方法。

    如果 datetime 不支持 %f 并且不需要 try/except 的解决方案是:

        (dt, mSecs) = row[5].strip().split(".") 
        dt = datetime.datetime(*time.strptime(dt, "%Y-%m-%d %H:%M:%S")[0:6])
        mSeconds = datetime.timedelta(microseconds = int(mSecs))
        fullDateTime = dt + mSeconds 
    

    这适用于输入字符串“2010-10-06 09:42:52.266000”

    【讨论】:

    • dt.replace(microsecond=int(mSecs))
    • 这适用于 Python 2.5 及更早版本。 Python 2.6 支持 strptime '%f'
    【解决方案3】:

    给出nstehr's answer 引用的代码(来自its source):

    def timeparse(t, format):
        """Parse a time string that might contain fractions of a second.
    
        Fractional seconds are supported using a fragile, miserable hack.
        Given a time string like '02:03:04.234234' and a format string of
        '%H:%M:%S', time.strptime() will raise a ValueError with this
        message: 'unconverted data remains: .234234'.  If %S is in the
        format string and the ValueError matches as above, a datetime
        object will be created from the part that matches and the
        microseconds in the time string.
        """
        try:
            return datetime.datetime(*time.strptime(t, format)[0:6]).time()
        except ValueError, msg:
            if "%S" in format:
                msg = str(msg)
                mat = re.match(r"unconverted data remains:"
                               " \.([0-9]{1,6})$", msg)
                if mat is not None:
                    # fractional seconds are present - this is the style
                    # used by datetime's isoformat() method
                    frac = "." + mat.group(1)
                    t = t[:-len(frac)]
                    t = datetime.datetime(*time.strptime(t, format)[0:6])
                    microsecond = int(float(frac)*1e6)
                    return t.replace(microsecond=microsecond)
                else:
                    mat = re.match(r"unconverted data remains:"
                                   " \,([0-9]{3,3})$", msg)
                    if mat is not None:
                        # fractional seconds are present - this is the style
                        # used by the logging module
                        frac = "." + mat.group(1)
                        t = t[:-len(frac)]
                        t = datetime.datetime(*time.strptime(t, format)[0:6])
                        microsecond = int(float(frac)*1e6)
                        return t.replace(microsecond=microsecond)
    
            raise
    

    【讨论】:

      【解决方案4】:

      DNS answer above 实际上是不正确的。 SO询问毫秒,但答案是微秒。不幸的是,Python 没有毫秒指令,只有微秒(参见doc),但您可以通过在字符串末尾附加三个零并将字符串解析为微秒来解决它,例如:

      datetime.strptime(time_str + '000', '%d/%m/%y %H:%M:%S.%f')
      

      其中time_str 的格式类似于30/03/09 16:31:32.123

      希望这会有所帮助。

      【讨论】:

      • 我最初也有同样的想法,但请参阅答案中的 cmets 和 docs。它是 left-zero-padded 微秒,因此 .123 被正确解释为 123,000 微秒
      【解决方案5】:

      我的第一个想法是尝试传递它 '30/03/09 16:31:32.123' (在秒和毫秒之间使用句点而不是冒号。)但这不起作用。快速浏览一下文档表明在任何情况下都会忽略小数秒...

      啊,版本差异。这是reported as a bug,现在在 2.6+ 中,您可以使用 "%S.%f" 来解析它。

      【讨论】:

      • 那不行; time.strptime 只是不做毫秒。
      【解决方案6】:

      来自 python 邮件列表:parsing millisecond thread。那里发布了一个似乎可以完成工作的功能,尽管正如作者的 cmets 中提到的那样,它是一种 hack。它使用正则表达式来处理引发的异常,然后进行一些计算。

      您也可以尝试在将其传递给 strptime 之前预先执行正则表达式和计算。

      【讨论】:

      • 是的,我知道那个帖子。但我正在寻找一种更简单的方法。标准 python 库中是否有任何模块可以以毫秒为单位进行时间解析?
      【解决方案7】:

      对于 python 2 我做了这个

      print ( time.strftime("%H:%M:%S", time.localtime(time.time())) + "." + str(time.time()).split(".",1)[1])
      

      它打印时间 "%H:%M:%S" ,将 time.time() 拆分为两个子字符串(之前和之后。) xxxxxxx.xx 并且由于 .xx 是我的毫秒数,我将第二个子字符串添加到我的“%H:%M:%S”

      希望这是有道理的 :) 示例输出:

      13:31:21.72 眨眼01


      13:31:21.81 闪烁结束 01


      13:31:26.3 眨眼01


      13:31:26.39 闪烁结束 01


      13:31:34.65 01车道出发


      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-27
        • 2012-05-23
        • 2012-06-16
        • 2012-10-28
        • 2015-10-17
        • 2018-10-02
        • 1970-01-01
        相关资源
        最近更新 更多