HOWTO · Python

Convertire un datetime Python in stringa con millisecondi

Converti un datetime Python in una stringa ISO o personalizzata con esattamente tre cifre di millisecondi.

In questa pagina

Usa value.isoformat(timespec="milliseconds") quando è adatto un risultato in stile ISO. Usa strftime() con %f e rimuovi le ultime tre cifre quando ti serve un layout personalizzato. Entrambi gli approcci troncano i microsecondi a millisecondi invece di arrotondarli.

La formattazione cambia la rappresentazione, non il valore datetime stesso. Gli esempi usano input fissi in modo che l’output possa essere verificato esattamente; sostituisci quei costruttori con un valore della tua applicazione dopo aver scelto il layout richiesto. Se il sistema ricevente si aspetta un offset, rendi il valore consapevole del fuso orario prima di formattarlo.

Usa isoformat() per una precisione in millisecondi a tre cifre

datetime.isoformat() è la scelta più chiara per una stringa in stile ISO 8601. L’argomento timespec="milliseconds" emette sempre esattamente tre cifre frazionarie di secondo. È disponibile in Python 3.6 e versioni successive.

Passa esattamente la stringa plurale minuscola "milliseconds". Altri valori supportati di timespec selezionano livelli di precisione diversi, mentre un valore sconosciuto genera ValueError. Questo parametro esplicito è preferibile al comportamento predefinito "auto" quando uno schema a valle richiede una larghezza di campo costante.

Il seguente esempio deterministico usa un datetime consapevole del fuso orario, quindi il risultato mostra anche che isoformat() conserva l’offset 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"))

Output:

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

Il valore microsecond a sei cifre 789654 diventa .789. Python non arrotonda il valore a .790; timespec controlla quali componenti appaiono e i componenti temporali esclusi vengono troncati.

Usa un datetime consapevole del fuso orario quando la stringa deve identificare un istante reale tra sistemi. Un valore naive non ha offset UTC, quindi il suo testo formattato non può distinguere da solo un’ora locale da UTC o da un altro fuso.

isoformat() conserva l’offset già collegato all’oggetto; non converte il valore in UTC. Normalizza prima il datetime se il tuo contratto dati richiede UTC. Al contrario, ometti la conversione del fuso solo quando il consumatore si aspetta deliberatamente un valore locale.

Usa strftime() per un layout personalizzato

Usa strftime() quando devi controllare ordine, separatori o altri campi. La direttiva %f produce sei cifre di microsecondi. Lo slicing con [:-3] rimuove deliberatamente le ultime tre cifre e lascia precisione in millisecondi:

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

Output:

2026-09-16 12:34:56.789

Questo slicing è sicuro perché %f fornisce sempre un campo a sei cifre riempito con zeri, anche quando il valore originale non ha microsecondi. Mantieni .%f alla fine del formato prima di usare [:-3]; altrimenti lo slice potrebbe rimuovere caratteri da un altro campo.

L’operazione tronca invece di arrotondare. Per esempio, 789999 microsecondi diventa comunque 789 millisecondi. Se una specifica richiede arrotondamento, arrotonda il datetime prima della formattazione e gestisci un possibile riporto al secondo successivo; tagliare %f non può implementare quella regola.

Lo stile di import determina come chiami la classe. Con from datetime import datetime, chiama datetime.now(). Se invece scrivi import datetime, chiama datetime.datetime.now().

Comprendi str() e i limiti dello slicing

Un semplice str(value) equivale a value.isoformat(" "). Il suo timespec="auto" predefinito omette il campo frazionario quando microsecond è zero e altrimenti emette tutte e sei le cifre dei microsecondi. Quindi str(value) non garantisce un campo di millisecondi a tre cifre e applicare [:-3] alla cieca non è sicuro.

Questo comportamento a larghezza variabile è utile per visualizzazione informale, ma non è adatto a un campo a larghezza fissa. Controllare un punto decimale prima dello slicing eviterebbe di corrompere i secondi, ma duplicherebbe logica già gestita da isoformat(timespec="milliseconds") e richiederebbe ulteriore attenzione per i suffissi di fuso orario.

Questo esempio limite mostra anche che l’output in millisecondi viene troncato a 999999 microsecondi e che il valore singolare "millisecond" non è valido:

"""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}")

Output:

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

La terza riga non è una conversione valida in millisecondi: rimuove :56 perché l’input non ha un campo frazionario. Preferisci isoformat(timespec="milliseconds") oppure usa un formato contenente %f, invece di tagliare il risultato a lunghezza variabile di str().

Scegli il metodo appropriato

Usa isoformat(timespec="milliseconds") per timestamp leggibili da macchine e scambio standard. Gestisce microsecondi zero, troncamento e offset di fuso orario senza manipolazione manuale delle stringhe. Usa strftime() più [:-3] quando un consumatore richiede un layout personalizzato.

Scegli in base al contratto di output, non alla comodità: isoformat() fornisce una forma data-ora standardizzata, strftime() fornisce una forma definita dal chiamante e str() fornisce un valore predefinito amichevole per l’uomo con precisione frazionaria variabile. In ogni caso documenta se un offset mancante significa ora locale, UTC per convenzione o fuso sconosciuto.

Questi metodi formattano un datetime esistente; non lo convertono in millisecondi dall’epoca Unix né analizzano una stringa in un datetime. Ricorda inoltre che tre cifre visualizzate descrivono precisione in millisecondi, non necessariamente l’accuratezza dell’orologio o del valore sorgente memorizzato.