Formatieren Sie eine Datums- / Uhrzeitangabe in eine Zeichenfolge mit Millisekunden

168

Ich möchte eine datetimeZeichenfolge vom Datum mit Millisekunden haben. Dieser Code ist typisch für mich und ich bin gespannt darauf, wie man ihn verkürzt.

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
quelle
3
Bitte schreiben Sie einen Titel, der Ihr Problem beschreibt, und versuchen Sie, Ihre Frage klar und auf den Punkt zu bringen.
Agf
Erwähnenswert ist hier, dass zusätzliche Präzision oft in Ordnung ist. Zum Beispiel kann Java Instant.parseRepräsentation analysieren, die mitstrftime('%Y-%m-%dT%H:%M:%S.%fZ')
Jarek Przygódzki

Antworten:

350

Verwenden Sie Folgendes, um eine Datumszeichenfolge mit Millisekunden (3 Dezimalstellen hinter Sekunden) zu erhalten:

from datetime import datetime

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

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

Hinweis: Für Python3 printsind Klammern erforderlich:

print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
Jeremy Moritz
quelle
1
Um genau zu sein, 2013-08-23 10:18:32.926ist die Ausgabe von print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] .
Jaan
3
Beachten Sie, wenn Sie import datetimeanstelle von verwenden möchten from datetime import datetime, müssen Sie dies verwenden:datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
Luc
17
Wenn die
8
Beachten Sie, dass dies abgeschnitten und nicht auf Millisekunden gerundet wird
Gens
2
Wie Gens erwähnt, wird das nicht falsch sein, wenn die Zahl der ersten Tropfen> = 5 ist. In der Tat, wenn der usec-Teil> 999500 ist, dann werden Sie nie die richtige Zeit bekommen, wenn Sie mit dem Mikrosekunden-Teil herumspielen
Chris
58

Mit Python 3.6 können Sie Folgendes verwenden:

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

Ausgabe:

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

Weitere Informationen finden Sie hier: https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat

Lorenzo
quelle
Nützlich auch für die Zeitzone: date = datetime (2019,5,10) date_with_tz = pytz.timezone ('Europe / Rome'). Localize (date) date_with_tz.isoformat (sep = 'T', timespec = 'milliseconds') Ausgabe: '2019-05-10T00: 00: 00.000 + 02: 00'
Ena
Dies ist die eigentliche Lösung, die akzeptiert werden sollte. Und das isoformat () ist das, was ich für den Export ins GPX-Format brauche, vielen Dank!
Filip Happy
22
print datetime.utcnow().strftime('%Y%m%d%H%M%S%f')

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

stricken
quelle
13
Zu Ihrer Information, dies gibt Mikrosekunden als die letzten 6 Ziffern aus. Fügen Sie [:-3]am Ende hinzu, um die letzten 3 Ziffern zu löschen, sodass nur Millisekunden angezeigt werden.
Mark Lakata
5
Mikrosekunden können weniger als 6 Stellen haben, also
druckt
13
Was ist, wenn wir Zeitzone haben?
Devrimbaris 4.
1
@ ᐅ devrimbaris für Zeitzonen-Checkout Lorenzos Antwort
Ena
17

@Cabbi hat das Problem angesprochen, dass auf einigen Systemen das Mikrosekundenformat auftreten %fkann. Daher ist "0"es nicht portabel, die letzten drei Zeichen einfach abzuschneiden.

Der folgende Code formatiert einen Zeitstempel sorgfältig mit Millisekunden:

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

Beispielausgabe:

2016-02-26 04:37:53.133

Um die genaue Ausgabe zu erhalten, die das OP wollte, müssen wir Interpunktionszeichen entfernen:

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

Beispielausgabe:

20160226043839901
Sam Watkins
quelle
6
Was ich tatsächlich mache, ist Folgendes: print '% s.% 03d'% (dt.strftime ("% Y-% m-% d% H:% M:% S"), int (dt.microsecond / 1000) ))
cabbi
2
stimme @cabbi zu, es ist nicht nötig, mit string und int
caoanan
Ja, ich stimme auch zu ... :)
Sam Watkins
1
Diese Antwort ist viel präziser und sicherer als die anderen. Vielen Dank !
Hunaphu
5

Wahrscheinlich so:

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
quelle
Die zweite %mmuss eine sein %M, denn es sind Minuten, keine Monate.
Michael Dorner
2

Ich nehme an, Sie meinen, Sie suchen nach etwas, das schneller als datetime.datetime.strftime () ist, und entfernen im Wesentlichen die Nicht-Alpha-Zeichen von einem utc-Zeitstempel.

Ihr Ansatz ist geringfügig schneller, und ich denke, Sie können die Dinge noch schneller machen, indem Sie die Schnur durchschneiden:

>>> 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
quelle
@oxtopus Gute Arbeit. Persönlich verwende ich timeit nicht mehr zur einfachen Zeitmessung. Es ist seltsam, dass die Zeitverhältnisse bei Ihrem Code unterschiedlich sind: 1 - 0,67 - 0,53 und bei meinem: 1 - 0,35 - 0,20, für die Methoden strftime - replace - slicing
eyquem
Vielleicht etwas damit zu tun, dass str (datetime.datetime.utcnow ()) in jeder Iteration des Tests aufgerufen wird, anstatt es einmal festzulegen?
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:] "

Ergebnis

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

Die Verwendung von translate () und der gleichzeitig ausgeführten Slicing- Methode
translate () bietet den Vorteil, dass sie in einer Zeile verwendet werden können

Vergleich der Zeiten anhand der ersten:

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

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

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

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

eyquem
quelle
1
Nett! Das ist in der Tat sauberer, ohne die Leistung zu beeinträchtigen. str.translate () tatsächlich schneller in meinen Tests.
Austin Marshall
1

Ich habe mich mit dem gleichen Problem befasst, aber in meinem Fall war es wichtig, dass die Millisekunde gerundet und nicht abgeschnitten wurde

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

<<<<<< AUSGABE >>>>>>>

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

Das Problem mit datetime.utcnow()und anderen solchen Lösungen ist, dass sie langsam sind.

Eine effizientere Lösung könnte folgendermaßen aussehen:

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

Wo precwäre 3in Ihrem Fall (Millisekunden).

Die Funktion arbeitet mit bis zu 9 Dezimalstellen (bitte Nummer 9in der 2. Formatierungszeichenfolge notieren ).

Wenn Sie den Bruchteil runden möchten, würde ich vorschlagen, "%.9f"dynamisch mit der gewünschten Anzahl von Dezimalstellen zu erstellen.

mato
quelle