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

问题描述 投票:0回答:8

我能够使用 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
8个回答
413
投票

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
 微秒。


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

如果日期时间不支持 %f 并且无需尝试/例外,解决方案是:

(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”


4
投票
给出

nstehr的答案所指的代码(来自其来源):

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

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

其中

time_str

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

希望这有帮助。


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

啊,版本差异。这被

报告为错误,现在在 2.6+ 中你可以使用“%S.%f”来解析它。


1
投票
来自 python 邮件列表:

解析毫秒线程。那里发布了一个函数,似乎可以完成工作,尽管正如作者评论中提到的那样,它是一种黑客攻击。它使用正则表达式来处理引发的异常,然后进行一些计算。

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


1
投票
对于 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



0
投票
创建自定义格式化程序是我发现的最方便的方法。

from datetime import datetime import pytz d = datetime.fromisoformat("2022-08-05 08:47:50.17+00").astimezone(pytz.utc) print(f"{d.year:04d}-{d.month:02d}-{d.day:02d}T{d.hour:02d}:{d.minute:02d}:{d.second:02d}.{int(d.microsecond/1000):02d}Z")
所以,格式化后的值为:

2022-08-05T08:47:50.170Z


    

© www.soinside.com 2019 - 2024. All rights reserved.