Формат даты и времени в строку с миллисекундами

169

Я хочу получить datetimeстроку с датой в миллисекундах. Этот код типичен для меня, и мне не терпится узнать, как его сократить.

from datetime import datetime

timeformatted= str(datetime.utcnow())
semiformatted= timeformatted.replace("-","")
almostformatted= semiformatted.replace(":","")
formatted=almostformatted.replace(".","")
withspacegoaway=formatted.replace(" ","")
formattedstripped=withspacegoaway.strip()
print formattedstripped
Jurudocs
источник
3
Пожалуйста, напишите название, которое описывает вашу проблему, и постарайтесь, чтобы ваш вопрос был ясным и понятным.
AGF
Здесь стоит упомянуть, что дополнительная точность часто просто прекрасна. Например, Java Instant.parseможет анализировать представление, созданное с помощьюstrftime('%Y-%m-%dT%H:%M:%S.%fZ')
Jarek Przygódzki

Ответы:

354

Чтобы получить строку даты с миллисекундами (3 десятичных знака после секунд), используйте это:

from datetime import datetime

print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]

>>>> OUTPUT >>>>
2020-05-04 10:18:32.926

Примечание. Для Python3 printтребуются скобки:

print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
Джереми Мориц
источник
1
Чтобы быть точным, 2013-08-23 10:18:32.926это результат print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] .
Яан
3
Обратите внимание, если вы хотите использовать import datetimeвместо from datetime import datetime, вы должны будете использовать это:datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
Люк
17
Если микросекунды равны 0, в Windows 2.7 реализация микросекунд не распечатывается, поэтому обрезает секунды :(
cabbi
8
обратите внимание, что это усекает, а не округляет до миллисекунд
gens
2
Как упоминает Генс, не ошибется ли это, если первое число капель> = 5 ?. Фактически, если часть usec> 999500, то вы никогда не получите правильное время, играя с частью микросекунд
Chris
59

С Python 3.6 вы можете использовать:

from datetime import datetime
datetime.utcnow().isoformat(sep=' ', timespec='milliseconds')

Вывод:

'2019-05-10 09:08:53.155'

Более подробная информация здесь: https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat

Lorenzo
источник
Также полезно с часовым поясом: date = datetime (2019,5,10) date_with_tz = pytz.timezone ('Europe / Rome'). Localize (date) date_with_tz.isoformat (sep = 'T', timespec = 'milliseconds') вывод: '2019-05-10T00: 00: 00.000 + 02: 00'
Ena
Это фактическое решение, которое должно быть принято. И isoformat () - это то, что мне нужно для экспорта в формат GPX, большое спасибо!
Филип С Днем
22
print datetime.utcnow().strftime('%Y%m%d%H%M%S%f')

http://docs.python.org/library/datetime.html#strftime-strptime-behavior

knitti
источник
13
К вашему сведению, это печатает микросекунды как последние 6 цифр. Добавьте [:-3]в конец последние 3 цифры, чтобы отображались только миллисекунды.
Марк Лаката
5
микросекунды могут быть меньше 6 цифр, поэтому [: -3] выводит неправильные миллисекунды
cabbi
13
что если у нас есть часовой пояс?
ᐅ devrimbaris
1
@ ᐅ devrimbaris для проверки часового пояса Ответ Лоренцо
Эна
17

@Cabbi поднял вопрос о том, что в некоторых системах формат микросекунд %fможет дать "0", так что невозможно просто отрубить последние три символа.

Следующий код тщательно форматирует метку времени с миллисекундами:

from datetime import datetime
(dt, micro) = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f').split('.')
dt = "%s.%03d" % (dt, int(micro) / 1000)
print dt

Пример вывода:

2016-02-26 04:37:53.133

Чтобы получить точный вывод, который хотел ОП, нам нужно убрать знаки препинания:

from datetime import datetime
(dt, micro) = datetime.utcnow().strftime('%Y%m%d%H%M%S.%f').split('.')
dt = "%s%03d" % (dt, int(micro) / 1000)
print dt

Пример вывода:

20160226043839901
Сэм Уоткинс
источник
6
То, что я на самом деле делаю, это: выведите «% s.% 03d»% (dt.strftime («% Y-% m-% d% H:% M:% S»), int (dt.microsecond / 1000 ))
cabbi
2
согласен с @cabbi, нет необходимости конвертировать туда и обратно со строкой и int
caoanan
да, я тоже согласен ... :)
Сэм Уоткинс,
1
Этот ответ гораздо более точный и безопасный, чем другие. Спасибо !
Хунапху
5

Вероятно, так:

import datetime
now = datetime.datetime.now()
now.strftime('%Y/%m/%d %H:%M:%S.%f')[:-3]  
# [:-3] => Removing the 3 last characters as %f is for microsecs.
N Fayçal
источник
Второе %mдолжно быть %M, потому что это минуты, а не месяцы.
Майкл Дорнер
2

Я предполагаю, что вы имеете в виду, что вы ищете что-то более быстрое, чем datetime.datetime.strftime (), и по сути извлекаете не-альфа-символы из временной метки utc.

Ваш подход немного быстрее, и я думаю, что вы можете ускорить процесс, нарезав строку:

>>> import timeit
>>> t=timeit.Timer('datetime.utcnow().strftime("%Y%m%d%H%M%S%f")','''
... from datetime import datetime''')
>>> t.timeit(number=10000000)
116.15451288223267

>>> def replaceutc(s):
...     return s\
...         .replace('-','') \
...         .replace(':','') \
...         .replace('.','') \
...         .replace(' ','') \
...         .strip()
... 
>>> t=timeit.Timer('replaceutc(str(datetime.datetime.utcnow()))','''
... from __main__ import replaceutc
... import datetime''')
>>> t.timeit(number=10000000)
77.96774983406067

>>> def sliceutc(s):
...     return s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]
... 
>>> t=timeit.Timer('sliceutc(str(datetime.utcnow()))','''
... from __main__ import sliceutc
... from datetime import datetime''')
>>> t.timeit(number=10000000)
62.378515005111694
Остин Маршалл
источник
@oxtopus Хорошая работа. Лично я больше не использую время для простого измерения времени. Это странно , что отношения времени различны с кодом: 1 - 0,67 - 0,53 и с моим: 1 - 0,35 - 0,20, для методов STRFTIME - заменить - нарезки
Eyquem
Может быть, что-то делать с функцией str (datetime.datetime.utcnow ()), вызываемой на каждой итерации теста, против ее установки один раз?
Остин Маршалл
1
from datetime import datetime
from time import clock

t = datetime.utcnow()
print 't == %s    %s\n\n' % (t,type(t))

n = 100000

te = clock()
for i in xrange(1):
    t_stripped = t.strftime('%Y%m%d%H%M%S%f')
print clock()-te
print t_stripped," t.strftime('%Y%m%d%H%M%S%f')"

print

te = clock()
for i in xrange(1):
    t_stripped = str(t).replace('-','').replace(':','').replace('.','').replace(' ','')
print clock()-te
print t_stripped," str(t).replace('-','').replace(':','').replace('.','').replace(' ','')"

print

te = clock()
for i in xrange(n):
    t_stripped = str(t).translate(None,' -:.')
print clock()-te
print t_stripped," str(t).translate(None,' -:.')"

print

te = clock()
for i in xrange(n):
    s = str(t)
    t_stripped = s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:] 
print clock()-te
print t_stripped," s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:] "

результат

t == 2011-09-28 21:31:45.562000    <type 'datetime.datetime'>


3.33410112179
20110928212155046000  t.strftime('%Y%m%d%H%M%S%f')

1.17067364707
20110928212130453000 str(t).replace('-','').replace(':','').replace('.','').replace(' ','')

0.658806915404
20110928212130453000 str(t).translate(None,' -:.')

0.645189262881
20110928212130453000 s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]

Использование translate () и метода нарезки, выполняемых одновременно,
translate () дает преимущество, которое можно использовать в одной строке

Сравнивая время на основе первого:

1.000 * t.strftime ('% Y% m% d% H% M% S% f')

0,351 * str (t) .replace ('-', ''). Replace (':', ''). Replace ('.', ''). Replace ('', '')

0,198 * str (t) .translate (Нет, '- :.')

0,194 * с [: 4] + с [5: 7] + с [8:10] + с [11:13] + с [14:16] + с [17:19] + с [20:]

Eyquem
источник
1
Ницца! Это действительно чище, не жертвуя производительностью. str.translate () на самом деле быстрее в моем тестировании.
Остин Маршалл
1

Я имел дело с той же проблемой, но в моем случае было важно, чтобы миллисекунда была округлена, а не усечена.

from datetime import datetime, timedelta

def strftime_ms(datetime_obj):
    y,m,d,H,M,S = datetime_obj.timetuple()[:6]
    ms = timedelta(microseconds = round(datetime_obj.microsecond/1000.0)*1000)
    ms_date = datetime(y,m,d,H,M,S) + ms
    return ms_date.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
omdaniel
источник
1
import datetime

# convert string into date time format.

str_date = '2016-10-06 15:14:54.322989'
d_date = datetime.datetime.strptime(str_date , '%Y-%m-%d %H:%M:%S.%f')
print(d_date)
print(type(d_date)) # check d_date type.


# convert date time to regular format.

reg_format_date = d_date.strftime("%d %B %Y %I:%M:%S %p")
print(reg_format_date)

# some other date formats.
reg_format_date = d_date.strftime("%Y-%m-%d %I:%M:%S %p")
print(reg_format_date)
reg_format_date = d_date.strftime("%Y-%m-%d %H:%M:%S")
print(reg_format_date)

<<<<<< ВЫХОД >>>>>>>

2016-10-06 15:14:54.322989    
<class 'datetime.datetime'>    
06 October 2016 03:14:54 PM    
2016-10-06 03:14:54 PM    
2016-10-06 15:14:54
Вакас Али
источник
1
python -c "from datetime import datetime; print str(datetime.now())[:-3]"
2017-02-09 10:06:37.006
arntg
источник
0
datetime
t = datetime.datetime.now()
ms = '%s.%i' % (t.strftime('%H:%M:%S'), t.microsecond/1000)
print(ms)
14:44:37.134
Hunaphu
источник
0

Проблема с datetime.utcnow()другими решениями заключается в том, что они медленные.

Более эффективное решение может выглядеть так:

def _timestamp(prec=0):
    t = time.time()
    s = time.strftime("%H:%M:%S", time.localtime(t))
    if prec > 0:
        s += ("%.9f" % (t % 1,))[1:2+prec]
    return s

Где precбы 3в вашем случае (миллисекунды).

Функция работает до 9 знаков после запятой (обратите внимание на номер 9во второй строке форматирования).

Если вы хотите округлить дробную часть, я бы предложил строить "%.9f"динамически с желаемым количеством десятичных знаков.

мато
источник