Conserva un valore di pubblicazione con sola data analizzandolo come data di calendario e mantenendo tale data come riferimento autorevole. Se un’esportazione richiede un timestamp UTC, aggiungi una convenzione esplicita che preveda la mezzanotte UTC. Questa guida passo passo per il Terminale del Mac illustra la differenza e verifica il round trip.

Stabilisci che cosa rappresenta davvero il campo di pubblicazione

Supponiamo che un elenco di pubblicazioni contenga il valore sintetico 2028-06-15. Il tuo compito è convalidare quel valore e prepararlo per un’esportazione senza visualizzare per errore il 14 giugno. Prima di scegliere un parser, stabilisci se il campo registra il giorno di pubblicazione o un effettivo momento di pubblicazione.

Questi quattro concetti hanno ruoli diversi:

Concetto Esempio sintetico Significato
Data civile 2028-06-15 Un giorno di calendario, senza ora né offset
Istante 2028-06-15T00:00:00+00:00 Un momento preciso espresso in UTC
Offset UTC +09:00 La differenza tra l’ora indicata da un orologio locale e l’UTC
Fuso orario con nome America/Los_Angeles Un identificatore usato per ottenere le regole applicabili al fuso orario

RFC 3339 definisce separatamente una full-date e un date-time; la grammatica del timestamp aggiunge un’ora e un offset alla data. Una data di pubblicazione senza altri elementi non contiene quindi le informazioni necessarie per identificare un istante di pubblicazione. Scegliere la mezzanotte aggiunge informazioni che mancavano nell’input. RFC 3339, sezione 5.6

Anche un fuso orario con nome contiene più informazioni di un singolo offset numerico. La documentazione di Python su zoneinfo mostra come un fuso possa usare offset diversi durante il passaggio all’ora legale. Per un’etichetta con sola data non è necessario risolvere queste regole. Python: supporto per i fusi orari IANA

Prima di esportare, segui questa regola decisionale:

  • Il campo significa “pubblicato in questo giorno”: conserva un valore con sola data durante l’archiviazione e la visualizzazione.
  • Il formato di destinazione richiede un timestamp: conserva la data e ricava un valore veicolo con mezzanotte UTC secondo una convenzione documentata.
  • Il campo significa “pubblicato in questo momento”: procurati l’ora e l’offset effettivi, oppure l’ora e il fuso orario con nome necessari a stabilire quel momento.

La convenzione del valore veicolo è utile per la compatibilità, ma non permette di recuperare un orario di pubblicazione sconosciuto. Un nome di campo come utc_carrier rende evidente questa limitazione; chiamarlo published_at suggerirebbe informazioni mai fornite dalla fonte.

Capisci dove si verifica l’errore del giorno precedente

Considera due possibili percorsi di elaborazione per 2028-06-15. Nel primo, un programma inventa la mezzanotte all’offset fisso +09:00, poi converte quell’istante in UTC. Il risultato è 2028-06-14T15:00:00+00:00: sottraendo nove ore si oltrepassa il confine della data.

Nel secondo percorso, il programma crea intenzionalmente la mezzanotte UTC: 2028-06-15T00:00:00+00:00. Visualizzando lo stesso istante all’offset fisso -07:00 si ottiene 2028-06-14T17:00:00-07:00. Si tratta di calcoli illustrativi sugli offset, non di affermazioni sull’offset di un fuso orario con nome in quella data.

Entrambi i calcoli conservano i rispettivi istanti. Nessuno dei due conserva l’etichetta originale del calendario in ogni fuso orario di visualizzazione. Python documenta che astimezone() modifica i campi dell’orologio preservando l’ora UTC rappresentata. Python: datetime.astimezone()

La conseguenza pratica è che analisi e visualizzazione devono rispettare un contratto condiviso. Se una data è stata inserita in un valore veicolo con mezzanotte UTC, recuperane i campi di calendario in UTC. Se vuoi che l’etichetta di pubblicazione resti invariata ovunque venga aperta l’esportazione, visualizza la data civile conservata.

Non dare per scontato che ogni linguaggio fornisca le stesse informazioni mancanti. ECMAScript specifica che i formati con sola data e senza offset vengono interpretati come UTC, mentre i formati di data e ora senza offset vengono interpretati come ora locale. Aggiungere T00:00:00 a una stringa può quindi cambiarne l’interpretazione in JavaScript. ECMAScript: Date.parse

Esegui un controllo completo della data di pubblicazione nel Terminale del Mac

Questa procedura convalida tre date sintetiche, stampa un’anteprima delimitata da tabulazioni e verifica il rifiuto degli input malformati. Non modifica un elenco di pubblicazioni né crea un file di esportazione.

In Finder, apri /Applications/Utilities, quindi fai doppio clic su Terminal. Apple documenta questo metodo come un modo supportato per aprire l’app a riga di comando. Apple: aprire o chiudere Terminale sul Mac

Esegui il comando seguente per controllare l’interprete:

python3 --version

Per questa procedura usa Python 3.11 o versioni successive. Se python3 non è disponibile o indica una versione precedente, segui le istruzioni ufficiali per l’installazione su macOS prima di continuare, quindi riapri Terminal e controlla di nuovo. Python documenta sia il proprio programma d’installazione per macOS sia l’esecuzione di script con python3. Python: usare Python su macOS

Incolla l’intero blocco qui sotto, compreso l’ultimo PY, quindi premi Return. L’argomento - indica a Python di leggere il programma dallo standard input. Sono inclusi tutti i dati di esempio e gli import. Python: riga di comando e ambiente

python3 - <<'PY'
import re
from datetime import date, datetime, time, timezone


def parse_publication_date(text):
    if not isinstance(text, str) or re.fullmatch(
        r"[0-9]{4}-[0-9]{2}-[0-9]{2}", text
    ) is None:
        raise ValueError("Expected YYYY-MM-DD")
    return date.fromisoformat(text)


def utc_carrier(day):
    return datetime.combine(day, time(0), tzinfo=timezone.utc)


samples = ["2028-02-29", "2028-06-15", "2028-12-31"]
parsed = [(text, parse_publication_date(text)) for text in samples]

print("publication_date\tutc_carrier")
for original, day in parsed:
    carrier = utc_carrier(day)
    assert day.isoformat() == original
    assert carrier.astimezone(timezone.utc).date() == day
    print(day.isoformat(), carrier.isoformat(timespec="seconds"), sep="\t")

for invalid in [
    "2027-02-29",
    "2028-6-15",
    "2028-06-15T00:00:00",
    " 2028-06-15",
]:
    try:
        parse_publication_date(invalid)
    except ValueError:
        pass
    else:
        raise AssertionError(f"Unexpected acceptance: {invalid!r}")

print("Round-trip and rejection checks passed.")
PY

L’output previsto è:

publication_date	utc_carrier
2028-02-29	2028-02-29T00:00:00+00:00
2028-06-15	2028-06-15T00:00:00+00:00
2028-12-31	2028-12-31T00:00:00+00:00
Round-trip and rejection checks passed.

L’esempio e i due calcoli con offset fissi sono stati eseguiti correttamente con l’interprete Python disponibile. Le istruzioni specifiche per il Mac, relative all’apertura e all’interprete, seguono la documentazione ufficiale collegata.

Perché l’esempio conserva il giorno di pubblicazione

Il parser controlla separatamente due aspetti: la forma esatta della stringa e la validità della data di calendario. La sua espressione regolare richiede quattro cifre per l’anno, due per il mese e due per il giorno. Il parser di date successivo rifiuta le date impossibili. In questo modo si evita che una colonna di pubblicazione accetti tacitamente timestamp, spazi iniziali o finali o input abbreviati.

Il controllo esplicito della forma è importante perché date.fromisoformat() accetta anche altre rappresentazioni ISO, comprese le date compatte e quelle basate sulla settimana. datetime.combine() fornisce quindi intenzionalmente mezzanotte e UTC. Python: tipi fondamentali di data e ora

Il programma analizza l’intero elenco di esempio prima di stampare l’intestazione. Se sostituisci un campione con un valore non valido, l’esecuzione si interrompe prima che compaiano righe di anteprima. I controlli deliberati degli input non validi alla fine sono test separati; le eccezioni previste vengono intercettate affinché si possano verificare tutti i casi di rifiuto.

Due asserzioni di round trip esprimono il contratto. La prima verifica che l’analisi e la formattazione della data riproducano l’etichetta originale. La seconda verifica che il valore veicolo derivato restituisca la stessa data quando interpretato in UTC. Insieme, controllano l’esatto requisito di conservazione, invece di limitarsi a verificare se sia possibile produrre un timestamp qualsiasi.

L’output usa esplicitamente +00:00. RFC 3339 ammette anche Z come indicatore dell’offset UTC, ma aggiungere uno di questi suffissi a una data senza altri elementi non fornisce la componente oraria mancante. Mantieni la forma con sola data oppure crea intenzionalmente il timestamp completo. RFC 3339, sezione 5.6

Diagnostica un’esportazione che continua a modificare la data

Se un’anteprima successiva mostra il giorno precedente, controlla i valori a ogni passaggio. Usa il campione sintetico centrale, 2028-06-15, così potrai confrontare ogni fase con un’unica etichetta nota.

Punto di controllo Valore previsto secondo la convenzione del valore veicolo Cosa suggerisce una differenza
Campo di pubblicazione originale 2028-06-15 L’input è cambiato prima dell’analisi
Data analizzata e resa come testo 2028-06-15 L’analisi o la normalizzazione ha modificato l’etichetta
Valore veicolo UTC derivato 2028-06-15T00:00:00+00:00 È stata introdotta un’ora o un offset diverso
Data recuperata in UTC 2028-06-15 La conversione o l’estrazione ha seguito il contratto sbagliato
Etichetta di pubblicazione mostrata al lettore 2028-06-15 Il visualizzatore potrebbe mostrare il valore veicolo in un altro fuso orario

Controlla il visualizzatore separatamente dal parser. Un valore veicolo UTC corretto può comunque produrre un giorno di calendario diverso se visualizzato secondo l’impostazione del fuso orario locale. Per un’etichetta di pubblicazione, fornisci al visualizzatore il valore conservato con sola data. Se accetta solo timestamp, usa un’opzione di visualizzazione UTC documentata e verifica il risultato.

Se lo strumento di destinazione supporta solo istanti e li visualizza sempre localmente, la convenzione della mezzanotte UTC non può garantire un’etichetta di data invariata. Conserva una colonna di testo separata con la sola data, usa un campo con sola data supportato oppure scegli un visualizzatore con formattazione UTC esplicita. Questa limitazione deriva dai calcoli degli offset riportati sopra; modificare solo il parser non può eliminarla.

Inoltre, evita di trattare un timestamp esistente come se fosse un input con sola data. Per un istante autentico, cambiare il fuso orario significa convertirlo. Python distingue tale operazione dalla sostituzione di tzinfo, che assegna informazioni sul fuso senza modificare i campi dell’orologio. Python: comportamento della conversione del fuso orario

Per il tuo elenco di pubblicazioni, mantieni publication_date come valore di calendario autorevole. Ricava un valore veicolo UTC solo quando un’interfaccia lo richiede, accompagna il campo con la convenzione e verifica l’estrazione in UTC prima di fidarti dell’anteprima. In questo modo hai una procedura ripetibile per conservare il giorno fornito senza inventare un momento di pubblicazione.

Fonti