Formatta un datetime in una stringa con millisecondi


169

Voglio avere una datetimestringa dalla data con millisecondi. Questo codice è tipico per me e non vedo l'ora di imparare come accorciarlo.

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


3
Scrivi un titolo che descriva il tuo problema e prova a mantenere la domanda chiara e precisa.
agf,

Vale la pena ricordare che la precisione extra spesso va bene. Ad esempio, Java Instant.parsepuò analizzare la rappresentazione creata constrftime('%Y-%m-%dT%H:%M:%S.%fZ')
Jarek Przygódzki

Risposte:


354

Per ottenere una stringa di data con millisecondi (3 decimali dietro i secondi), usa questo:

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: per Python3, sono printnecessarie le parentesi:

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

1
Per essere precisi, 2013-08-23 10:18:32.926è l'output di print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] .
Jaan,

3
Nota, se vuoi usare import datetimeinvece di from datetime import datetime, dovrai usare questo:datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
Luc

17
Nel caso in cui i microsecondi siano 0, nell'implementazione di Windows 2.7 i microsecondi non vengono stampati, quindi ritaglia i secondi :(
cabbi

8
si noti che questo tronca, non si trasforma in millisecondi
gens

2
Come menziona gens, questo non sbaglierà se il primo numero di gocce è> = 5 ?. In effetti se la parte usec è> 999500, allora non avrai mai il tempo giusto armeggiando con la parte microsecondi
Chris,

59

Con Python 3.6 puoi usare:

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

Produzione:

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

Maggiori informazioni qui: https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat


Utile anche con il fuso orario: date = datetime (2019,5,10) date_with_tz = pytz.timezone ('Europe / Rome'). Localize (date) date_with_tz.isoformat (sep = 'T', timespec = 'millisecondi') output: '2019-05-10T00: 00: 00.000 + 02: 00'
Ena

Questa è la soluzione reale che dovrebbe essere accettata. E isoformat () è quello che mi serve per esportare in formato GPX, grazie mille!
Filip Happy

22
print datetime.utcnow().strftime('%Y%m%d%H%M%S%f')

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


13
Cordiali saluti, questo stampa microsecondi come le ultime 6 cifre. Aggiungi [:-3]alla fine per eliminare le ultime 3 cifre in modo da visualizzare solo i millisecondi.
Mark Lakata,

5
i microsecondi possono contenere meno di 6 cifre, quindi [: -3] stampa millisecondi errati
cabbi

13
e se avessimo il fuso orario?
ᐅ devrimbaris

1
@ Screenshot devrimbaris per il check-out del fuso orario Risposta di Lorenzo
Ena,

17

@Cabbi ha sollevato il problema che su alcuni sistemi %fpotrebbe dare il formato dei microsecondi "0", quindi non è portatile tagliare semplicemente gli ultimi tre caratteri.

Il codice seguente formatta attentamente un timestamp con millisecondi:

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

Esempio di output:

2016-02-26 04:37:53.133

Per ottenere l'output esatto desiderato dall'OP, è necessario eliminare i caratteri di punteggiatura:

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

Esempio di output:

20160226043839901

6
Quello che sto effettivamente facendo è questo: print '% s.% 03d'% (dt.strftime ("% Y-% m-% d% H:% M:% S"), int (dt.microsecond / 1000 ))
cabbi

2
d'accordo con @cabbi, non è necessario convertire avanti e indietro con stringhe e int
caoanan

sì, anch'io sono d'accordo ... :)
Sam Watkins,

1
Questa risposta è molto più precisa e sicura delle altre. Grazie !
Hunaphu

5

Probabilmente in questo modo:

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.

Il secondo %mdeve essere un %M, perché sono minuti, non mesi.
Michael Dorner,

2

Suppongo che intendi che stai cercando qualcosa che è più veloce di datetime.datetime.strftime () e che essenzialmente stai togliendo i caratteri non alfa da un timestamp utc.

Il tuo approccio è leggermente più veloce e penso che puoi accelerare ancora di più tagliando la stringa:

>>> 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 Ottimo lavoro. Personalmente, non uso più timeit per una semplice misurazione del tempo. È strano che i rapporti dei tempi siano diversi con il tuo codice: 1 - 0.67 - 0.53 e con il mio: 1 - 0.35 - 0.20, per i metodi strftime - sostituzione - taglio
eyquem

Forse qualcosa a che fare con lo str (datetime.datetime.utcnow ()) chiamato in ogni iterazione del test vs impostandolo una volta?
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:] "

risultato

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

L'uso di translate () e il metodo slicing eseguiti allo stesso tempo
translate () presenta il vantaggio di essere utilizzabili in una riga

Confrontando i tempi sulla base del primo:

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

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

0,198 * str (t) .translate (Nessuno, '- :.')

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


1
Bello! Questo è davvero più pulito senza sacrificare le prestazioni. str.translate () in realtà più veloce nei miei test.
Austin Marshall,

1

Ho affrontato lo stesso problema, ma nel mio caso era importante che il millisecondo fosse arrotondato e non troncato

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]

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)

<<<<<< OUTPUT >>>>>>>

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

0
datetime
t = datetime.datetime.now()
ms = '%s.%i' % (t.strftime('%H:%M:%S'), t.microsecond/1000)
print(ms)
14:44:37.134

0

Il problema con datetime.utcnow() e altre soluzioni simili è che sono lente.

Una soluzione più efficiente può apparire come questa:

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

Dove precsarebbe3 nel tuo caso (millisecondi).

La funzione funziona fino a 9 cifre decimali (notare il numero 9 nella seconda stringa di formattazione).

Se desideri arrotondare la parte frazionaria, suggerirei di costruire "%.9f"dinamicamente con il numero desiderato di cifre decimali.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.