Formatee una fecha y hora en una cadena con milisegundos

169

Quiero tener una datetimecadena de la fecha con milisegundos. Este código es típico para mí y estoy ansioso por aprender cómo acortarlo.

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
fuente
3
Escriba un título que describa su problema e intente mantener su pregunta clara y al grano.
agf
Vale la pena mencionar aquí que la precisión adicional a menudo está bien. Por ejemplo, Java Instant.parsepuede analizar la representación creada constrftime('%Y-%m-%dT%H:%M:%S.%fZ')
Jarek Przygódzki

Respuestas:

354

Para obtener una cadena de fecha con milisegundos (3 lugares decimales detrás de los segundos), use esto:

from datetime import datetime

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

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

Nota: Para Python3, printrequiere paréntesis:

print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
Jeremy Moritz
fuente
1
Para ser precisos, 2013-08-23 10:18:32.926es la salida de print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] .
Jaan
3
Tenga en cuenta que si desea usar en import datetimelugar de from datetime import datetime, tendrá que usar esto:datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
Luc
17
En caso de que los microsegundos sean 0, en la implementación de Windows 2.7 los microsegundos no se imprimen, por lo que recorta segundos :(
cabbi
8
tenga en cuenta que esto se trunca, no se redondea a milisegundos
gens
2
Como menciona Gens, ¿no se equivocará si el primer número de gotas es> = 5? De hecho, si la parte usec es> 999500, entonces nunca obtendrá el momento adecuado jugando con la parte microsegundos
Chris
59

Con Python 3.6 puedes usar:

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

Salida:

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

Más información aquí: https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat

Lorenzo
fuente
Útil también con la zona horaria: date = datetime (2019,5,10) date_with_tz = pytz.timezone ('Europe / Rome'). Localize (date) date_with_tz.isoformat (sep = 'T', timespec = 'milliseconds') output: '2019-05-10T00: 00: 00.000 + 02: 00'
Ena
Esta es la solución real que debe ser aceptada. Y el isoformat () es lo que necesito para exportar a formato GPX, ¡muchas gracias!
Filip Happy
22
print datetime.utcnow().strftime('%Y%m%d%H%M%S%f')

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

knitti
fuente
13
Para su información, esto imprime microsegundos como los últimos 6 dígitos. Agregue [:-3]al final para soltar los últimos 3 dígitos para que solo muestre milisegundos.
Mark Lakata
55
microsegundos pueden tener menos de 6 dígitos, por lo que [: -3] está imprimiendo milisegundos incorrectos
cabbi
13
¿Qué pasa si tenemos zona horaria?
ᐅ devrimbaris el
1
@ ᐅ devrimbaris para la comprobación de zona horaria Respuesta de Lorenzo
Ena
17

@Cabbi planteó el problema de que en algunos sistemas, el formato de microsegundos %fpuede dar "0", por lo que no es portátil simplemente cortar los últimos tres caracteres.

El siguiente código formatea cuidadosamente una marca de tiempo con milisegundos:

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

Salida de ejemplo:

2016-02-26 04:37:53.133

Para obtener el resultado exacto que quería el OP, tenemos que quitar los caracteres de puntuación:

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

Salida de ejemplo:

20160226043839901
Sam Watkins
fuente
66
Lo que realmente estoy haciendo es esto: print '% s.% 03d'% (dt.strftime ("% Y-% m-% d% H:% M:% S"), int (dt.microsecond / 1000 ))
cabbi
2
de acuerdo con @cabbi, no hay necesidad de convertir de un lado a otro con string y int
caoanan
sí, también estoy de acuerdo ... :)
Sam Watkins
1
Esta respuesta es mucho más precisa y segura que las otras. Gracias !
Hunaphu
5

Probablemente así:

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
fuente
El segundo %mdebe ser un %M, porque son minutos, no meses.
Michael Dorner
2

Supongo que quiere decir que está buscando algo que sea más rápido que datetime.datetime.strftime (), y esencialmente está eliminando los caracteres no alfa de una marca de tiempo utc.

Su enfoque es marginalmente más rápido, y creo que puede acelerar las cosas aún más cortando la cadena:

>>> 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
Austin Marshall
fuente
@oxtopus Buen trabajo. Personalmente, ya no uso el tiempo para medir el tiempo. Es extraño que las proporciones de tiempos sean diferentes con su código: 1 - 0.67 - 0.53 y con el mío: 1 - 0.35 - 0.20, para los métodos strftime - replace - slicing
eyquem
¿Quizás algo relacionado con el str (datetime.datetime.utcnow ()) que se llama en cada iteración de la prueba en lugar de configurarlo una vez?
Austin Marshall
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:] "

resultado

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

El uso de translate () y el método de segmentación ejecutado al mismo tiempo
translate () presenta la ventaja de ser utilizable en una línea

Comparando los tiempos en base al primero:

1.000 * t. Tiempo de ejecución ('% Y% m% d% H% M% S% f')

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

0.198 * str (t) .translate (Ninguno, '- :.')

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

eyquem
fuente
1
¡Agradable! De hecho, eso es más limpio sin sacrificar el rendimiento. str.translate () en realidad más rápido en mis pruebas.
Austin Marshall
1

Abordé el mismo problema, pero en mi caso era importante que el milisegundo fuera redondeado y no truncado.

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

<<<<<< SALIDA >>>>>>>

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
Waqas Ali
fuente
1
python -c "from datetime import datetime; print str(datetime.now())[:-3]"
2017-02-09 10:06:37.006
Arntg
fuente
0
datetime
t = datetime.datetime.now()
ms = '%s.%i' % (t.strftime('%H:%M:%S'), t.microsecond/1000)
print(ms)
14:44:37.134
Hunaphu
fuente
0

El problema con datetime.utcnow()y otras soluciones es que son lentas.

Una solución más eficiente puede verse así:

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

Dónde precestaría 3en su caso (milisegundos).

La función funciona con hasta 9 decimales (tenga en cuenta el número 9en la segunda cadena de formato).

Si desea redondear la parte fraccional, sugeriría construir "%.9f"dinámicamente con el número deseado de lugares decimales.

mato
fuente