Bewahren Sie einen Veröffentlichungswert ohne Uhrzeit, indem Sie ihn als Kalenderdatum parsen und dieses Datum als maßgeblich beibehalten. Wenn ein Export einen UTC-Zeitstempel erfordert, ergänzen Sie eine ausdrückliche Konvention für UTC-Mitternacht. Diese Anleitung für das Mac-Terminal zeigt den Unterschied und testet die Rückkonvertierung.

Entscheiden, was das Veröffentlichungsfeld tatsächlich bedeutet

Angenommen, eine Veröffentlichungsliste enthält den synthetischen Wert 2028-06-15. Ihre Aufgabe ist es, diesen Wert zu validieren und für einen Export vorzubereiten, ohne versehentlich den 14. Juni anzuzeigen. Bevor Sie einen Parser auswählen, entscheiden Sie, ob das Feld einen Veröffentlichungstag oder einen tatsächlichen Veröffentlichungszeitpunkt erfasst.

Diese vier Konzepte haben unterschiedliche Funktionen:

Konzept Synthetisches Beispiel Bedeutung
Kalenderdatum 2028-06-15 Ein Kalendertag ohne Uhrzeit und Offset
Zeitpunkt 2028-06-15T00:00:00+00:00 Ein bestimmter, in UTC angegebener Moment
UTC-Offset +09:00 Die Differenz zwischen einer lokalen Uhrzeit und UTC
Benannte Zeitzone America/Los_Angeles Ein Bezeichner zum Abrufen der geltenden Zeitzonenregeln

RFC 3339 definiert ein full-date getrennt von einem date-time; seine Zeitstempelgrammatik ergänzt das Datum um eine Uhrzeit und einen Offset. Ein bloßes Veröffentlichungsdatum enthält daher nicht genügend Informationen, um einen Veröffentlichungszeitpunkt zu bestimmen. Die Wahl von Mitternacht fügt Informationen hinzu, die in der Eingabe nicht enthalten waren. RFC 3339, Abschnitt 5.6

Eine benannte Zeitzone enthält ebenfalls mehr Informationen als ein einzelner numerischer Offset. Die Dokumentation zu Python-zoneinfo zeigt, wie eine Zeitzone während einer Zeitumstellung unterschiedliche Offsets verwenden kann. Für eine Datumsangabe ohne Uhrzeit müssen diese Regeln nicht aufgelöst werden. Python: IANA-Zeitzonenunterstützung

Wenden Sie vor dem Export diese Entscheidungsregel an:

  • Das Feld bedeutet „an diesem Tag veröffentlicht“: Behalten Sie durchgängig einen Wert ohne Uhrzeit bei der Speicherung und Anzeige bei.
  • Das Zielformat erfordert einen Zeitstempel: Behalten Sie das Datum bei und leiten Sie nach einer dokumentierten Konvention einen UTC-Mitternachtswert als Träger ab.
  • Das Feld bedeutet „zu diesem Zeitpunkt veröffentlicht“: Ermitteln Sie die tatsächliche Uhrzeit und den Offset oder die Uhrzeit und benannte Zeitzone, die zur Bestimmung dieses Zeitpunkts erforderlich sind.

Die Trägerkonvention ist für die Kompatibilität nützlich, stellt aber keine unbekannte Veröffentlichungszeit wieder her. Ein Feldname wie utc_carrier macht diese Einschränkung sichtbar; die Bezeichnung published_at würde Informationen suggerieren, die die Quelle nie geliefert hat.

Verstehen, wo der Fehler mit dem Vortag entsteht

Betrachten Sie zwei mögliche Verarbeitungspfade für 2028-06-15. Im ersten erfindet ein Programm Mitternacht mit dem festen Offset +09:00 und wandelt diesen Zeitpunkt anschließend in UTC um. Das Ergebnis ist 2028-06-14T15:00:00+00:00: Durch das Abziehen von neun Stunden wird die Datumsgrenze überschritten.

Im zweiten Pfad erzeugt das Programm bewusst UTC-Mitternacht: 2028-06-15T00:00:00+00:00. Wird derselbe Zeitpunkt mit dem festen Offset -07:00 dargestellt, ergibt sich 2028-06-14T17:00:00-07:00. Dies sind veranschaulichende Offsetberechnungen und keine Aussagen über den Offset einer benannten Zeitzone an diesem Datum.

Beide Berechnungen bewahren jeweils ihren Zeitpunkt. Keine von beiden bewahrt die ursprüngliche Kalenderangabe bei jeder Darstellung in einer beliebigen Zeitzone. Python dokumentiert, dass astimezone() die Uhrzeitfelder anpasst und dabei den dargestellten UTC-Zeitpunkt beibehält. Python: datetime.astimezone()

In der Praxis müssen Parsing und Darstellung daher auf einer gemeinsamen Vereinbarung beruhen. Wenn ein Datum als UTC-Mitternachtswert übertragen wurde, rufen Sie seine Kalenderfelder in UTC ab. Wenn die Veröffentlichungsangabe beim Öffnen des Exports unverändert bleiben soll, zeigen Sie das beibehaltene Kalenderdatum an.

Gehen Sie nicht davon aus, dass jede Sprache dieselben fehlenden Informationen ergänzt. ECMAScript legt fest, dass Datumsangaben ohne Offset und ohne Uhrzeit als UTC interpretiert werden, während Datums- und Uhrzeitangaben ohne Offset als Lokalzeit interpretiert werden. Das Anhängen von T00:00:00 an eine Zeichenfolge kann ihre Interpretation in JavaScript daher ändern. ECMAScript: Date.parse

Eine vollständige Prüfung des Veröffentlichungsdatums im Mac-Terminal ausführen

Diese Anleitung validiert drei synthetische Datumsangaben, gibt eine tabulatorgetrennte Vorschau aus und prüft die Zurückweisung fehlerhafter Eingaben. Sie ändert keine Veröffentlichungsliste und erstellt keine Exportdatei.

Öffnen Sie im Finder den Ordner /Applications/Utilities und doppelklicken Sie dann auf Terminal. Apple dokumentiert dies als unterstützte Methode zum Öffnen der Befehlszeilen-App. Apple: Terminal auf dem Mac öffnen oder beenden

Führen Sie den folgenden Befehl aus, um Ihren Interpreter zu prüfen:

python3 --version

Verwenden Sie für diese Anleitung Python 3.11 oder neuer. Wenn python3 nicht verfügbar ist oder eine ältere Version meldet, folgen Sie den offiziellen Installationsanweisungen für macOS, bevor Sie fortfahren. Öffnen Sie anschließend erneut Terminal und prüfen Sie die Version noch einmal. Python dokumentiert sowohl das macOS-Installationsprogramm als auch das Ausführen von Skripten mit python3. Python: Python unter macOS verwenden

Fügen Sie den gesamten folgenden Block einschließlich des abschließenden PY ein und drücken Sie Return. Das Argument - weist Python an, das Programm über die Standardeingabe einzulesen. Alle Beispieldaten und Importe sind enthalten. Python: Befehlszeile und Umgebung

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

Die erwartete Ausgabe lautet:

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.

Das Beispiel und die beiden Berechnungen mit festen Offsets wurden mit dem verfügbaren Python-Interpreter erfolgreich ausgeführt. Die Mac-spezifischen Anweisungen zum Öffnen des Terminals und zum Interpreter folgen der verlinkten offiziellen Dokumentation.

Warum das Beispiel den Veröffentlichungstag bewahrt

Der Parser prüft zwei Dinge getrennt: das genaue Zeichenfolgenformat und die Gültigkeit des Kalenderdatums. Sein regulärer Ausdruck verlangt vier Jahresziffern, zwei Monatsziffern und zwei Tagesziffern. Anschließend weist der Datumsparser unmögliche Datumsangaben zurück. So kann eine Veröffentlichungsspalte nicht unbemerkt Zeitstempel, Leerzeichen am Anfang oder Ende oder abgekürzte Eingaben akzeptieren.

Diese ausdrückliche Formatprüfung ist wichtig, weil date.fromisoformat() auch andere ISO-Darstellungen akzeptiert, darunter kompakte Datumsangaben und Kalenderwochenangaben. datetime.combine() ergänzt dann bewusst Mitternacht und UTC. Python: Grundlegende Datums- und Uhrzeittypen

Das Programm parst die gesamte Beispielliste, bevor es die Kopfzeile ausgibt. Wenn Sie ein Beispiel durch einen ungültigen Wert ersetzen, wird die Ausführung angehalten, bevor Vorschauzeilen erscheinen. Die gezielten Prüfungen ungültiger Eingaben am Ende sind separate Tests; die erwarteten Ausnahmen werden abgefangen, damit alle Zurückweisungsfälle geprüft werden können.

Zwei Assertions für die Rückkonvertierung drücken die Vereinbarung aus. Die erste prüft, ob Parsing und Datumsformatierung die ursprüngliche Angabe wiederherstellen. Die zweite prüft, ob der abgeleitete Träger in UTC interpretiert dasselbe Datum ergibt. Zusammen prüfen sie die genaue Aufgabe der Werterhaltung, statt lediglich zu prüfen, ob sich irgendein Zeitstempel erzeugen lässt.

Die Ausgabe verwendet ausdrücklich +00:00. RFC 3339 erlaubt als UTC-Offsetbezeichner auch Z, doch keine dieser Endungen ergänzt eine bloße Datumsangabe um die fehlende Uhrzeit. Behalten Sie die Datumsform ohne Uhrzeit bei oder erstellen Sie bewusst den vollständigen Zeitstempel. RFC 3339, Abschnitt 5.6

Einen Export untersuchen, der das Datum weiterhin ändert

Wenn eine nachgelagerte Vorschau den Vortag anzeigt, prüfen Sie die Werte an jeder Verarbeitungsgrenze. Verwenden Sie das mittlere synthetische Beispiel 2028-06-15, damit Sie jede Phase mit einer bekannten Angabe vergleichen können.

Prüfpunkt Erwartung gemäß Trägerkonvention Was eine Abweichung vermuten lässt
Ursprüngliches Veröffentlichungsfeld 2028-06-15 Die Eingabe wurde vor dem Parsing geändert
Geparstes Datum als Text dargestellt 2028-06-15 Parsing oder Normalisierung hat die Angabe geändert
Abgeleiteter UTC-Träger 2028-06-15T00:00:00+00:00 Eine andere Uhrzeit oder ein anderer Offset wurde eingeführt
In UTC abgerufenes Datum 2028-06-15 Bei der Konvertierung oder Extraktion wurde die falsche Vereinbarung verwendet
Dem Leser angezeigte Veröffentlichungsangabe 2028-06-15 Möglicherweise zeigt der Viewer den Träger in einer anderen Zeitzone an

Prüfen Sie den Renderer unabhängig vom Parser. Ein korrekter UTC-Träger kann bei der Darstellung mit einer lokalen Zeitzoneneinstellung weiterhin ein anderes Kalenderdatum ergeben. Übergeben Sie dem Renderer für eine Veröffentlichungsangabe den beibehaltenen Datumswert ohne Uhrzeit. Wenn er nur Zeitstempel akzeptiert, verwenden Sie eine dokumentierte UTC-Anzeigeoption und überprüfen Sie das Ergebnis.

Wenn das empfangende Tool nur Zeitpunkte unterstützt und sie immer lokal darstellt, kann die UTC-Mitternachtskonvention keine unveränderte Datumsangabe garantieren. Bewahren Sie eine separate Textspalte mit dem Datum ohne Uhrzeit auf, verwenden Sie ein unterstütztes Datumsfeld oder wählen Sie einen Renderer mit ausdrücklicher UTC-Formatierung. Die Einschränkung ergibt sich aus den obigen Offsetberechnungen; allein durch eine Änderung des Parsers lässt sie sich nicht beseitigen.

Behandeln Sie außerdem einen vorhandenen Zeitstempel nicht so, als wäre er eine Eingabe ohne Uhrzeit. Bei einem tatsächlichen Zeitpunkt bedeutet eine Änderung der Zeitzone, ihn umzurechnen. Python unterscheidet diesen Vorgang vom Ersetzen von tzinfo, bei dem Zeitzoneninformationen angefügt werden, ohne die Uhrzeitfelder anzupassen. Python: Verhalten bei der Zeitzonenumrechnung

Behalten Sie für Ihre Veröffentlichungsliste publication_date als maßgeblichen Kalenderwert bei. Leiten Sie einen UTC-Träger nur an einer Schnittstelle ab, die einen solchen erfordert, dokumentieren Sie die Konvention zusammen mit dem Feld und prüfen Sie die UTC-Extraktion, bevor Sie der Vorschau vertrauen. So lässt sich der vorgegebene Tag zuverlässig bewahren, ohne einen Veröffentlichungszeitpunkt zu erfinden.

Quellen