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

发布于 2024-07-15 19:51:33 字数 560 浏览 5 评论 0原文

我能够使用 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

I am able to parse strings containing date/time with 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)

How can I parse a time string that contains milliseconds?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

老旧海报 2024-07-22 19:51:33

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

Python 2.6 added a new strftime/strptime macro %f. The docs are a bit misleading as they only mention microseconds, but %f actually parses any decimal fraction of seconds with up to 6 digits, meaning it also works for milliseconds or even centiseconds or deciseconds.

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

However, time.struct_time doesn't actually store milliseconds/microseconds. You're better off using datetime, like this:

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

As you can see, .123 is correctly interpreted as 123 000 microseconds.

悲歌长辞 2024-07-22 19:51:33

我知道这是一个较旧的问题,但我仍在使用 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”

I know this is an older question but I'm still using Python 2.4.3 and I needed to find a better way of converting the string of data to a datetime.

The solution if datetime doesn't support %f and without needing a try/except is:

(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 

This works for the input string "2010-10-06 09:42:52.266000"

≈。彩虹 2024-07-22 19:51:33

给出代码 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

To give the code that nstehr's answer refers to (from 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
相守太难 2024-07-22 19:51:33

上面的 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

希望这可以帮助。

DNS answer above is actually incorrect. The SO is asking about milliseconds but the answer is for microseconds. Unfortunately, Python`s doesn't have a directive for milliseconds, just microseconds (see doc), but you can workaround it by appending three zeros at the end of the string and parsing the string as microseconds, something like:

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

where time_str is formatted like 30/03/09 16:31:32.123.

Hope this helps.

仅此而已 2024-07-22 19:51:33

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

啊,版本差异。 这是报告为错误< /a> 现在在 2.6+ 中你可以使用“%S.%f”来解析它。

My first thought was to try passing it '30/03/09 16:31:32.123' (with a period instead of a colon between the seconds and the milliseconds.) But that didn't work. A quick glance at the docs indicates that fractional seconds are ignored in any case...

Ah, version differences. This was reported as a bug and now in 2.6+ you can use "%S.%f" to parse it.

薄荷→糖丶微凉 2024-07-22 19:51:33

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

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

from python mailing lists: parsing millisecond thread. There is a function posted there that seems to get the job done, although as mentioned in the author's comments it is kind of a hack. It uses regular expressions to handle the exception that gets raised, and then does some calculations.

You could also try do the regular expressions and calculations up front, before passing it to strptime.

熟人话多 2024-07-22 19:51:33

对于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


For python 2 i did this

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

it prints time "%H:%M:%S" , splits the time.time() to two substrings (before and after the .) xxxxxxx.xx and since .xx are my milliseconds i add the second substring to my "%H:%M:%S"

hope that makes sense :)
Example output:

13:31:21.72
Blink 01


13:31:21.81
END OF BLINK 01


13:31:26.3
Blink 01


13:31:26.39
END OF BLINK 01


13:31:34.65
Starting Lane 01


蓝天白云 2024-07-22 19:51:33

它使用 fromisoformat 检测格式,但挑战在于编写它。

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

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

It detects the format with fromisoformat, but the challenge lies in writing it.

Creating a custom formatter is the most convenient method that I have discovered.

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")

So, the formatted value is: 2022-08-05T08:47:50.170Z

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文