Как я могу разобрать временную строку, содержащую миллисекунды в ней, с помощью python?
-
22-08-2019 - |
Вопрос
Я могу анализировать строки, содержащие дату / время, с помощью время.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 2.6 добавил новый макрос strftime /strptime %f
, что составляет микросекунды.Не уверен, задокументировано ли это где-нибудь.Но если вы используете 2.6 или 3.0, вы можете сделать это:
time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
Редактировать:Я никогда по-настоящему не работаю с time
модуль, поэтому сначала я этого не заметил, но похоже, что 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
Другие советы
Я знаю, что это более старый вопрос, но я все еще использую Python 2.4.3, и мне нужно было найти лучший способ преобразования строки данных в datetime.
Решение, если 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".
Чтобы дать код, который ответ нстера относится к (из его источник):
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
Моей первой мыслью было попробовать передать его '30/03/09 16:31:32,123' (с точкой вместо двоеточия между секундами и миллисекундами.) Но это не сработало.Быстрый взгляд на документы показывает, что доли секунды в любом случае игнорируются...
Ах, различия в версиях.Это было сообщается как об ошибке и теперь в версии 2.6+ вы можете использовать "%S.%f" для его разбора.
из списков рассылки python: анализ миллисекундного потока.Там опубликована функция, которая, кажется, выполняет свою работу, хотя, как упоминалось в комментариях автора, это своего рода взлом.Он использует регулярные выражения для обработки возникающего исключения, а затем выполняет некоторые вычисления.
Вы также могли бы попробовать выполнить регулярные выражения и вычисления заранее, прежде чем передавать их в strptime.
Для 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
DNS-ответ выше на самом деле это неверно.SO спрашивает о миллисекундах, но ответ - о микросекундах.К сожалению, в Python нет директивы для миллисекунд, только микросекунды (см. док), но вы можете обойти это, добавив три нуля в конце строки и проанализировав строку в микросекундах, что-то вроде:
datetime.strptime(time_str + '000', '%d/%m/%y %H:%M:%S.%f')
где time_str
отформатирован следующим образом 30/03/09 16:31:32.123
.
Надеюсь, это поможет.