HOWTO · Python

Convertir un datetime Python en chaîne avec des millisecondes

Convertissez un datetime Python en chaîne ISO ou personnalisée avec exactement trois chiffres de millisecondes.

Sur cette page

Utilisez value.isoformat(timespec="milliseconds") lorsqu’un résultat de style ISO convient. Utilisez strftime() avec %f et supprimez ses trois derniers chiffres lorsque vous avez besoin d’une disposition personnalisée. Les deux approches tronquent les microsecondes en millisecondes au lieu de les arrondir.

Le formatage modifie la représentation, pas la valeur datetime elle-même. Les exemples utilisent des entrées fixes afin que leur sortie puisse être vérifiée exactement ; remplacez ces constructeurs par une valeur de votre application après avoir choisi la disposition requise. Si le système récepteur attend un décalage, rendez la valeur consciente du fuseau horaire avant de la formater.

Utilisez isoformat() pour une précision en millisecondes sur trois chiffres

datetime.isoformat() est le choix le plus clair pour une chaîne de style ISO 8601. L’argument timespec="milliseconds" émet toujours exactement trois chiffres fractionnaires de seconde. Il est disponible depuis Python 3.6.

Passez exactement la chaîne plurielle en minuscules "milliseconds". Les autres valeurs prises en charge de timespec choisissent d’autres niveaux de précision, tandis qu’une valeur inconnue lève ValueError. Ce paramètre explicite est préférable au comportement par défaut "auto" lorsqu’un schéma en aval exige une largeur de champ constante.

L’exemple déterministe suivant utilise un datetime avec fuseau horaire, ce qui montre aussi que isoformat() conserve le décalage UTC :

"""Show the recommended ISO-style millisecond formatting behavior."""

from datetime import datetime, timezone


value = datetime(2026, 9, 16, 12, 34, 56, 789654, tzinfo=timezone.utc)
print(value.isoformat(timespec="milliseconds"))

Sortie :

2026-09-16T12:34:56.789+00:00

La valeur microsecond à six chiffres 789654 devient .789. Python n’arrondit pas la valeur à .790 ; timespec contrôle les composants affichés, et les composants temporels exclus sont tronqués.

Utilisez un datetime avec fuseau horaire lorsque la chaîne doit identifier un instant réel entre systèmes. Une valeur naïve n’a pas de décalage UTC, donc son texte formaté ne peut pas distinguer à lui seul une heure locale de UTC ou d’un autre fuseau.

isoformat() conserve le décalage déjà attaché à l’objet ; il ne convertit pas la valeur en UTC. Normalisez d’abord le datetime si votre contrat de données exige UTC. À l’inverse, omettez la conversion de fuseau uniquement lorsque le consommateur attend volontairement une heure locale.

Utilisez strftime() pour une disposition personnalisée

Utilisez strftime() lorsque vous devez contrôler l’ordre, les séparateurs ou d’autres champs. La directive %f produit six chiffres de microsecondes. Le découpage avec [:-3] supprime volontairement les trois derniers chiffres et laisse une précision en millisecondes :

"""Show millisecond precision in a custom datetime string format."""

from datetime import datetime


value = datetime(2026, 9, 16, 12, 34, 56, 789654)
print(value.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3])

Sortie :

2026-09-16 12:34:56.789

Ce découpage est sûr parce que %f fournit toujours un champ à six chiffres complété par des zéros, même lorsque la valeur d’origine n’a pas de microsecondes. Gardez .%f à la fin du format avant d’utiliser [:-3] ; sinon, le découpage pourrait retirer des caractères d’un autre champ.

L’opération tronque au lieu d’arrondir. Par exemple, 789999 microsecondes devient encore 789 millisecondes. Si une spécification exige un arrondi, arrondissez le datetime avant le formatage et gérez un éventuel report à la seconde suivante ; découper %f ne peut pas appliquer cette règle.

Le style d’import détermine comment appeler la classe. Avec from datetime import datetime, appelez datetime.now(). Si vous écrivez plutôt import datetime, appelez datetime.datetime.now().

Comprenez str() et les limites du découpage

str(value) simple équivaut à value.isoformat(" "). Son timespec="auto" par défaut omet le champ fractionnaire lorsque microsecond vaut zéro et émet sinon les six chiffres de microsecondes. Ainsi, str(value) ne garantit pas un champ de millisecondes sur trois chiffres, et appliquer aveuglément [:-3] est dangereux.

Ce comportement à largeur variable est utile pour un affichage informel, mais il ne convient pas à un champ de largeur fixe. Vérifier la présence d’un point décimal avant de découper éviterait de corrompre les secondes, mais cela dupliquerait une logique déjà gérée par isoformat(timespec="milliseconds") et demanderait une attention supplémentaire pour les suffixes de fuseau horaire.

Cet exemple de limite montre aussi que la sortie en millisecondes est tronquée à 999999 microsecondes et que la valeur singulière "millisecond" est invalide :

"""Expose truncation, zero-microsecond slicing, and invalid-timespec boundaries."""

from datetime import datetime


almost_next_second = datetime(2026, 9, 16, 12, 34, 56, 999999)
without_fraction = datetime(2026, 9, 16, 12, 34, 56)

print(almost_next_second.isoformat(timespec="milliseconds"))
print(str(without_fraction))
print(str(without_fraction)[:-3])

try:
    without_fraction.isoformat(timespec="millisecond")
except ValueError as error:
    print(f"{type(error).__name__}: {error}")

Sortie :

2026-09-16T12:34:56.999
2026-09-16 12:34:56
2026-09-16 12:34
ValueError: Unknown timespec value

La troisième ligne n’est pas une conversion valide en millisecondes : elle retire :56 parce que l’entrée n’a pas de champ fractionnaire. Préférez isoformat(timespec="milliseconds"), ou utilisez un format contenant %f, au lieu de découper le résultat de longueur variable de str().

Choisissez la méthode appropriée

Utilisez isoformat(timespec="milliseconds") pour les horodatages lisibles par machine et les échanges standard. Cette méthode gère les microsecondes nulles, la troncature et les décalages de fuseau horaire sans manipulation manuelle de chaîne. Utilisez strftime() plus [:-3] lorsqu’un consommateur exige une disposition personnalisée.

Choisissez selon le contrat de sortie plutôt que par commodité : isoformat() fournit une forme date-heure standardisée, strftime() fournit une forme définie par l’appelant, et str() fournit une valeur par défaut lisible par l’humain avec une précision fractionnaire variable. Dans tous les cas, documentez si l’absence de décalage signifie heure locale, UTC par convention ou fuseau inconnu.

Ces méthodes formatent un datetime existant ; elles ne le convertissent pas en millisecondes depuis l’époque Unix et n’analysent pas une chaîne en datetime. Rappelez-vous aussi que trois chiffres affichés décrivent une précision en millisecondes, pas nécessairement l’exactitude de l’horloge ou de la valeur source stockée.