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


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

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


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


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

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.

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

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


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]

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

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

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.