Mettre en forme une date / heure en une chaîne en millisecondes

169

Je veux avoir une datetimechaîne de la date avec des millisecondes. Ce code est typique pour moi et j'ai hâte d'apprendre à le raccourcir.

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
la source
3
Veuillez écrire un titre qui décrit votre problème et essayez de garder votre question claire et précise.
agf
Il convient de mentionner ici qu'une précision supplémentaire est souvent très bien. Par exemple, Java Instant.parsepeut analyser la représentation créée avecstrftime('%Y-%m-%dT%H:%M:%S.%fZ')
Jarek Przygódzki

Réponses:

354

Pour obtenir une chaîne de date avec des millisecondes (3 décimales derrière les secondes), utilisez ceci:

from datetime import datetime

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

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

Remarque: pour Python3, printnécessite des parenthèses:

print(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
Jeremy Moritz
la source
1
Pour être précis, 2013-08-23 10:18:32.926est la sortie de print datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] .
Jaan
3
Notez que si vous souhaitez utiliser à la import datetimeplace de from datetime import datetime, vous devrez utiliser ceci:datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
Luc
17
Dans le cas où les microsecondes sont égales à 0, dans Windows 2.7, les microsecondes de mise en œuvre ne sont pas imprimées, donc il réduit les secondes :(
cabbi
8
notez que cela tronque, pas arrondit aux millisecondes
gens
2
Comme le mentionne la gens, cela ne va-t-il pas se tromper si le premier nombre de gouttes est> = 5 ?. En fait, si la partie usec est> 999500, vous n'obtiendrez jamais le bon moment en jouant avec la partie en microsecondes
Chris
59

Avec Python 3.6, vous pouvez utiliser:

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

Production:

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

Plus d'informations ici: https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat

Lorenzo
la source
Utile aussi avec le fuseau horaire: date = datetime (2019,5,10) date_with_tz = pytz.timezone ('Europe / Rome'). Localize (date) date_with_tz.isoformat (sep = 'T', timespec = 'millisecondes') output: '2019-05-10T00: 00: 00.000 + 02: 00'
Ena
C'est la solution réelle qui devrait être acceptée. Et l' isoformat () est ce dont j'ai besoin pour exporter au format GPX, merci beaucoup!
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
la source
13
FYI, cela imprime les microsecondes comme les 6 derniers chiffres. Ajoutez [:-3]à la fin pour supprimer les 3 derniers chiffres afin qu'il n'affiche que les millisecondes.
Mark Lakata
5
les microsecondes peuvent être inférieures à 6 chiffres, donc [: -3] imprime des millisecondes erronées
cabbi
13
et si nous avons un fuseau horaire?
的 devrimbaris
1
@ 的 devrimbaris pour le paiement du fuseau horaire Réponse de Lorenzo
Ena
17

@Cabbi a soulevé le problème que sur certains systèmes, le format des microsecondes %f peut donner "0", il n'est donc pas portable de simplement couper les trois derniers caractères.

Le code suivant formate soigneusement un horodatage en millisecondes:

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

Exemple de sortie:

2016-02-26 04:37:53.133

Pour obtenir la sortie exacte souhaitée par l'OP, nous devons supprimer les caractères de ponctuation:

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

Exemple de sortie:

20160226043839901
Sam Watkins
la source
6
Voici ce que je suis en train de faire: print '% s.% 03d'% (dt.strftime ("% Y-% m-% d% H:% M:% S"), int (dt.microseconde / 1000 ))
cabbi
2
d'accord avec @cabbi, il n'est pas nécessaire de convertir d'avant en arrière avec string et int
caoanan
ouais je suis d'accord aussi ... :)
Sam Watkins
1
Cette réponse est beaucoup plus précise et sûre que les autres. Merci !
Hunaphu
5

Probablement comme ceci:

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
la source
Le second %mdoit être un %M, car il s'agit de minutes et non de mois.
Michael Dorner
2

Je suppose que vous voulez dire que vous recherchez quelque chose qui est plus rapide que datetime.datetime.strftime (), et qui supprime essentiellement les caractères non alpha d'un horodatage utc.

Votre approche est légèrement plus rapide, et je pense que vous pouvez accélérer les choses encore plus en coupant la chaîne:

>>> 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
la source
@oxtopus Bon travail. Personnellement, je n'utilise plus timeit pour une simple mesure du temps. Il est étrange que les rapports de temps sont différents avec votre code: 1 - 0,67 à 0,53 et avec le mien: 1 à 0,35 - 0,20, pour les méthodes strftime - remplacer - tranchage
eyquem
Peut-être quelque chose à voir avec le str (datetime.datetime.utcnow ()) appelé à chaque itération du test vs le définir une fois?
Austin Marshall le
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:] "

résultat

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'utilisation de translate () et de la méthode de découpage exécutée en même temps
translate () présente l'avantage d'être utilisable en une seule ligne

Comparaison des temps sur la base du premier:

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

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

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

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

eyquem
la source
1
Agréable! C'est en effet plus propre sans sacrifier les performances. str.translate () en fait plus rapide dans mes tests.
Austin Marshall
1

J'ai traité le même problème mais dans mon cas il était important que la milliseconde soit arrondie et non tronquée

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
la source
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)

<<<<<< SORTIE >>>>>>>

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

Le problème avec datetime.utcnow()et d'autres solutions de ce type est qu'elles sont lentes.

Une solution plus efficace peut ressembler à celle-ci:

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

precserait 3dans votre cas (millisecondes).

La fonction fonctionne jusqu'à 9 décimales (veuillez noter le nombre 9dans la 2ème chaîne de formatage).

Si vous souhaitez arrondir la partie fractionnaire, je vous suggère de construire "%.9f"dynamiquement avec le nombre souhaité de décimales.

mato
la source