Python: преобразование строки в метку времени с помощью микросекунд
Я хотел бы преобразовать строковый формат даты в метку времени с микросекундами
Я пробую следующее, но не ожидая результата:
"""input string date -> 2014-08-01 04:41:52,117
expected result -> 1410748201.117"""
import time
import datetime
myDate = "2014-08-01 04:41:52,117"
timestamp = time.mktime(datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple())
print timestamp
> 1410748201.0
Где прошло миллисекунды?
Ответы
Ответ 1
В кортеже времени нет слота для компонента микросекунд:
>>> import time
>>> import datetime
>>> myDate = "2014-08-01 04:41:52,117"
>>> datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple()
time.struct_time(tm_year=2014, tm_mon=8, tm_mday=1, tm_hour=4, tm_min=41, tm_sec=52, tm_wday=4, tm_yday=213, tm_isdst=-1)
Вам придется добавить их вручную:
>>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
>>> time.mktime(dt.timetuple()) + (dt.microsecond / 1000000.0)
1406864512.117
Другой метод, который вы могли бы использовать, - создать объект timedelta()
относительно эпохи, а затем получить метку времени с помощью timedelta.total_seconds()
:
epoch = datetime.datetime.fromtimestamp(0)
(dt - epoch).total_seconds()
Использование эпохи локального времени вполне осознанно, поскольку у вас есть наивное (не учитывающее часовой пояс) значение даты и времени. Этот метод может быть неточным, основываясь на истории вашего локального часового пояса, однако, см. Комментарий JF Sebastian. Вам нужно будет преобразовать наивное значение datetime в значение datetime с учетом часового пояса, сначала используя локальный часовой пояс, а затем вычесть эпоху с учетом часового пояса.
Таким образом, легче придерживаться timetuple()
+ микросекунды.
Демо-версия:
>>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
>>> epoch = datetime.datetime.fromtimestamp(0)
>>> (dt - epoch).total_seconds()
1406864512.117
Ответ 2
В Python 3.4 и позже вы можете использовать
timestamp = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timestamp()
Это не требует импорта модуля time
. Он также использует меньше шагов, поэтому он должен быть быстрее. Для более старых версий Python другие ответы, вероятно, ваш лучший вариант.
Однако полученная временная метка будет интерпретировать myDate по местному времени, а не по UTC, что может вызвать проблемы, если myDate было указано в UTC
Ответ 3
Где прошло миллисекунды?
Это легкая часть. Показ .timetuple()
вызывает их падение. Вы можете добавить их обратно с помощью атрибута .microsecond
. Метод datetime.timestamp()
из стандартной библиотеки работает таким образом для наивных объектов datetime:
def timestamp(self):
"Return POSIX timestamp as float"
if self._tzinfo is None:
return _time.mktime((self.year, self.month, self.day,
self.hour, self.minute, self.second,
-1, -1, -1)) + self.microsecond / 1e6
else:
return (self - _EPOCH).total_seconds()
Достаточно, если возможно, в вашем случае можно проигнорировать 1 час ошибок. Я предполагаю, что вам нужны микросекунды, и поэтому вы не можете игнорировать ошибки продолжительностью 1 час без изменений.
Преобразование локального времени, заданного как строка в метку времени POSIX, является сложной задачей в целом. Вы можете преобразовать местное время в UTC, а затем получить временную метку времени UTC.
Существуют две основные проблемы:
Оба могут быть решены с использованием базы данных tz (модуль pytz
в Python):
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone() # get pytz timezone corresponding to the local timezone
naive_d = datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
# a) raise exception for non-existent or ambiguous times
d = tz.localize(naive_d, is_dst=None)
## b) assume standard time, adjust non-existent times
#d = tz.normalize(tz.localize(naive_d, is_dst=False))
## c) assume DST is in effect, adjust non-existent times
#d = tz.normalize(tz.localize(naive_d, is_dst=True))
timestamp = d - datetime(1970, 1, 1, tzinfo=pytz.utc)
В результате объект timestamp
- a timedelta
, вы можете преобразовать его в секунды, миллисекунды и т.д.
Также разные системы могут вести себя по-разному вокруг/в течение прыжковых секунд. Большинство приложений могут игнорировать то, что они существуют.
В общем, может быть проще хранить метки времени POSIX в дополнение к местному времени, а не пытаться угадать его с локального времени.