100 votes

<div> datetime: Arrondi / couper le nombre de chiffres dans les microsecondes </div>

Actuellement, je consigne des informations et j'utilise mon propre formateur avec une formatTime() personnalisée :

def formatTime(self, _record, _datefmt):
    t = datetime.datetime.now()
    return t.strftime('%Y-%m-%d %H:%M:%S.%f')

Mon problème est que les microsecondes, %f, sont six chiffres. Est-il possible de n'afficher que trois chiffres, comme les premiers trois chiffres des microsecondes ?

130voto

steveha Points 24808

La manière la plus simple serait d'utiliser le tranchage pour simplement couper les trois derniers chiffres des microsecondes :

def format_time():
    t = datetime.datetime.now()
    s = t.strftime('%Y-%m-%d %H:%M:%S.%f')
    return s[:-3]

Je recommande fortement de simplement couper. J'ai déjà écrit du code de journalisation qui arrondissait les horodatages au lieu de les couper, et j'ai trouvé que c'était en fait un peu déroutant lorsque l'arrondi changeait le dernier chiffre. Il y avait du code chronométré qui s'arrêtait à un certain horodatage et pourtant il y avait des événements de journal avec cet horodatage en raison de l'arrondi. Plus simple et plus prévisible de simplement couper.

Si vous voulez vraiment arrondir le nombre plutôt que simplement le couper, c'est un peu plus de travail mais pas horrible :

def format_time():
    t = datetime.datetime.now()
    s = t.strftime('%Y-%m-%d %H:%M:%S.%f')
    head = s[:-7] # tout jusqu'au '.'
    tail = s[-7:] # le '.' et les 6 chiffres qui suivent
    f = float(tail)
    temp = "{:.03f}".format(f)  # pour Python 2.x: temp = "%.3f" % f
    new_tail = temp[1:] # temp[0] est toujours '0'; s'en débarrasser
    return head + new_tail

Vous pouvez évidemment simplifier ce qui précède avec moins de variables ; je voulais juste que ce soit très facile à suivre.

63voto

Rob Points 55

À partir de Python 3.6, le langage dispose de cette fonctionnalité intégrée :

def format_time():
    t = datetime.datetime.now()
    s = t.isoformat(timespec='milliseconds')
    return s

11voto

Eric Herot Points 321

Cette méthode doit toujours retourner un horodatage qui ressemble exactement à ceci (avec ou sans le fuseau horaire en fonction de savoir si l'objet dt en entrée en contient un) :

2016-08-05T18:18:54.776+0000

Elle prend un objet datetime en entrée (que vous pouvez obtenir avec datetime.datetime.now()). Pour obtenir le fuseau horaire comme dans mon exemple de sortie, vous devrez import pytz et passer datetime.datetime.now(pytz.utc).

import pytz, datetime

time_format(datetime.datetime.now(pytz.utc))

def time_format(dt):
    return "%s:%.3f%s" % (
        dt.strftime('%Y-%m-%dT%H:%M'),
        float("%.3f" % (dt.second + dt.microsecond / 1e6)),
        dt.strftime('%z')
    )   

J'ai remarqué que certaines des autres méthodes ci-dessus omettaient le zéro final s'il y en avait un (par exemple, 0.870 devenait 0.87) et cela posait problème pour l'analyseur auquel je fournissais ces horodatages. Cette méthode n'a pas ce problème.

5voto

Abdurrahman Points 51

Une solution simple qui devrait fonctionner dans tous les cas:

def format_time():
    t = datetime.datetime.now()
    if t.microsecond % 1000 >= 500:  # vérifier s'il y aura un arrondi
        t = t + datetime.timedelta(milliseconds=1)  # arrondi manuel
    return t.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]

Fondamentalement, vous effectuez un arrondi manuel sur l'objet date lui-même d'abord, puis vous pouvez sûrement couper les microsecondes.

5voto

user Points 389

Vous pouvez soustraire la date actuelle des microsecondes.

d = datetime.datetime.now()
current_time = d - datetime.timedelta(microseconds=d.microsecond)

Cela transformera 2021-05-14 16:11:21.916229 en 2021-05-14 16:11:21

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X