Terminieren fühlt sich an wie eine Uhr stellen. Du wählst einen Termin, WordPress setzt den Beitrag auf „Geplant“, und irgendwann am Morgen erscheint er. Genau dieses Gefühl trügt, sobald die Zeitzone der Website nicht die eigene ist. Auf bloggen.xyz ist — Stand August 2026 — keine Zeitzone eingetragen; die Installation rechnet damit in UTC. Die Beiträge hier erscheinen um 07:00 UTC, für deutsche Leser also um neun Uhr Sommerzeit. Wer im Editor neun Uhr eintippt, meint deshalb nicht neun Uhr deutscher Zeit, sondern neun Uhr UTC — und damit elf Uhr deutscher Sommerzeit.
Ich schreibe das als Werkstattbericht mit Anleitungsteil auf. Denn der Zeitzonenfehler war nur die erste von drei Annahmen, die beim Terminieren still danebenliegen können. Die zweite steckt im gespeicherten Zeitstempel, die dritte in dem Auslöser, der den Beitrag tatsächlich veröffentlicht — und der ist in WordPress keine Uhr, sondern ein zufällig vorbeikommender Seitenaufruf. Wer alle drei kennt, terminiert danach anders.
Beiträge terminieren auf einen Blick
- Terminieren heißt Status „future“: Du gibst ein Datum in der Zukunft an, WordPress speichert den Beitrag mit dem Status
futureund veröffentlicht ihn später — über die Oberfläche genauso wie über die REST-Schnittstelle. - Eine nicht gesetzte Zeitzone ist keine neutrale Einstellung: Ist unter Einstellungen → Allgemein weder ein Zeitzonenname noch ein Stundenversatz hinterlegt, rechnet die Installation in UTC. Wirklich leer ist das Auswahlfeld dabei nie — es zeigt dann
UTC+0. Neun Uhr terminiert heißt in diesem Fall elf Uhr für deutsche Leser im Sommer, zehn Uhr im Winter. - Über die Schnittstelle gehört
date_gmtgesetzt, nichtdate: Die REST-Referenz beschreibtdateals Datum in der Zeitzone der Website unddate_gmtals Datum in GMT. Solange keine Zeitzone gesetzt ist, ist nur die GMT-Angabe eindeutig. - Die Zeitzone später umzustellen lässt Bestandsbeiträge stehen: WordPress speichert je Beitrag eine Ortszeit in
post_dateund die UTC-Zeit inpost_date_gmt. Beim Umstellen wirdpost_datenicht neu berechnet, und die Anzeige greift auf dieses Feld zu. Die alten Zeiten bleiben also stehen und passen danach nicht mehr zur eingestellten Zone. Das ist eine bewusste Entscheidung, kein Handgriff zwischendurch. - WP-Cron ist keine Uhr: Das Plugin-Handbuch schreibt, WP-Cron laufe nicht dauerhaft wie ein System-Cron, sondern werde beim Seitenaufruf ausgelöst. Ohne Besucher passiert nichts.
- Missed schedule ist kein Beitragsstatus: Als Status registriert sind hier
publish,future,draft,pending,privateundtrash. Bleibt ein Beitrag auffuturestehen, obwohl der Termin vorbei ist, schreibt die Beitragsliste in die Datumsspalte den Hinweis Missed schedule, sinngemäß: verpasster Zeitplan. Deshalb schaue ich nach dem Termin einmal nach.

Wie Terminieren in WordPress funktioniert
Bevor ich zur Falle komme, der Mechanismus. Terminieren ist in WordPress kein eigenes Feature mit eigener Logik, sondern ein Zusammenspiel aus einem Status und einem Zeitstempel. Beides kannst du über die Oberfläche setzen oder über die Schnittstelle — und beide Wege verhalten sich in einem entscheidenden Punkt unterschiedlich.
Über die Oberfläche: ein Datum und ein Statuswechsel
Im Editor öffnest du rechts die Beitragseinstellungen und klickst beim Feld für die Veröffentlichung auf das Datum. Wählst du einen Zeitpunkt in der Zukunft, wechselt die Schaltfläche von „Veröffentlichen“ zu „Planen“. Nach dem Klick steht der Beitrag in der Übersicht unter „Geplant“. Intern ist das der Status future — die WordPress-Dokumentation führt ihn in ihrer Liste der Beitragsstatus als den Status für Beiträge, die zu einem späteren Zeitpunkt veröffentlicht werden sollen.
Was der Editor dir dabei nicht sagt: Die Uhrzeit, die er dir anzeigt, ist die Uhrzeit deiner Website, nicht die deines Rechners. Wenn beides auseinanderfällt, merkst du das im Editor nicht. Du siehst acht Uhr und denkst an deine acht Uhr.
Über die REST-Schnittstelle: status und date_gmt
Wer Beiträge über die Schnittstelle anlegt — bei mir läuft das über einen MCP-Server, ähnlich wie beim Schreiben der Yoast-Felder über die REST-API — hat zwei Felder zur Auswahl. Die REST-Referenz für Beiträge beschreibt sie knapp und präzise: date ist das Veröffentlichungsdatum in der Zeitzone der Website, date_gmt das Veröffentlichungsdatum in GMT. Als Status ist future in der Referenz ausdrücklich erlaubt.
| Feld | Bezug laut REST-Referenz | Eindeutig bei leerer Zeitzone? |
|---|---|---|
date | Zeitzone der Website | Nein — hängt an einer Einstellung, die hier nicht gesetzt ist |
date_gmt | GMT | Ja — ein fester Bezugspunkt |
Daraus folgt meine Regel für terminierte Beiträge über die Schnittstelle: Ich setze date_gmt und rechne den gewünschten deutschen Termin selbst um. Acht Uhr deutscher Sommerzeit sind sechs Uhr GMT. So sieht der Aufruf aus:
POST /wp-json/wp/v2/posts
{
"title": "Beitrag mit festem Termin",
"slug": "beitrag-mit-festem-termin",
"status": "future",
"date_gmt": "2026-09-01T06:00:00",
"content": "<!-- wp:paragraph -->\n<p>Text</p>\n<!-- /wp:paragraph -->"
}
Der Unterschied zu date ist unscheinbar und in der Wirkung groß. Schreibe ich "date": "2026-09-01T08:00:00", dann bittet das die Installation, acht Uhr in ihrer eigenen Zeitzone zu verstehen. Ist keine gesetzt, ist das acht Uhr UTC — also zehn Uhr deutscher Sommerzeit. Mit date_gmt gibt es diese Zwischenübersetzung nicht.
Die Zeitzonenfalle: eine leere Einstellung ist auch eine Einstellung
Jetzt der eigentliche Punkt. Er fällt nur auf, wenn man ihn einmal gezielt nachsieht — von selbst meldet er sich nicht, und im Editor sieht alles unauffällig aus.
Was in den Einstellungen steht (Stand August 2026)
Nichts. Genau das ist der Befund. In den Einstellungen von bloggen.xyz ist — Stand August 2026 — keine Zeitzone gesetzt: weder ein Zeitzonenname noch ein Stundenversatz, das Auswahlfeld steht auf UTC+0. Die Installation läuft damit auf UTC. Ein Beitrag, den ich auf neun Uhr terminiere, erscheint für deutsche Leser um elf Uhr Sommerzeit, im Winter um zehn. Exotisch ist dieser Zustand nach meinem Eindruck nicht: Bei alten Installationen, die irgendwann einmal aufgesetzt und danach nur noch beschrieben wurden, dürfte eine nie angefasste Zeitzone eher der Normalfall sein als die Ausnahme — belastbare Zahlen dazu habe ich nicht, das ist eine Einschätzung. Man merkt es nur nie, solange man alles sofort veröffentlicht.
Prüfen kannst du das in einer halben Minute: Einstellungen → Allgemein, dort das Feld für die Zeitzone. Die WordPress-Dokumentation zum Allgemein-Bildschirm empfiehlt, eine Stadt in derselben Zeitzone auszuwählen — für Deutschland also Berlin —, und weist darauf hin, dass du alternativ einen der Etc GMT-Werte nehmen kannst, wenn keine passende Stadt dabei ist. Nach dem Speichern zeigt WordPress laut Dokumentation die UTC-Zeit und die lokale Zeit an, damit du die Wahl bestätigen kannst. Genau dieser Vergleich ist der Test: Stehen dort zwei identische Uhrzeiten, obwohl du in Deutschland sitzt, läufst du auf UTC.
Warum die Umstellung kein Handgriff nebenbei ist
Die naheliegende Reaktion lautet: einfach Berlin eintragen, fertig. Sie hat eine Nebenwirkung, die man kennen sollte, bevor man klickt — nur eine andere, als die meisten vermuten. WordPress speichert zu jedem Beitrag zwei Zeitstempel: post_date, die Ortszeit zum Zeitpunkt der Veröffentlichung, und post_date_gmt, dieselbe Zeit in UTC. Die Anzeige greift auf post_date zu, und dieses Feld wird beim Umstellen der Zeitzone nicht neu berechnet.
Das ist an zwei Stellen nachzulesen. Im WordPress-Support-Forum beschreibt der Thread Timezone change doesn’t recalculate post_date from GMT in WordPress genau diese Aufteilung: post_date ist die Ortszeit der Veröffentlichung, post_date_gmt die zugehörige UTC-Zeit, Zeitzonenwechsel aktualisieren post_date bestehender Beiträge nicht rückwirkend, und die Ausgabe über get_the_date() beziehungsweise get_the_time() stützt sich auf dieses Feld. Das Trac-Ticket #57742 Post date time not updating after Timezone change hält denselben Befund fest: Nach einer Umstellung übernehmen nur neu veröffentlichte Beiträge die neue Zone, bereits veröffentlichte behalten ihre angezeigte Zeit, bis man sie einzeln anfasst.
Die Zeiten der Bestandsbeiträge wandern also nicht mit — sie bleiben stehen. Was sich ändert, ist ihr Bezug: Ab dem Umstellen passen die gespeicherten Ortszeiten nicht mehr zur eingestellten Zeitzone. Neue Beiträge werden in der neuen Zone gerechnet, alte behalten ihre alte Uhrzeit, und im Archiv steht danach beides nebeneinander.
Für ein kleines Blog ist das verkraftbar. Trotzdem behandle ich es als eigene Entscheidung mit eigenem Termin und nicht als Beifang einer anderen Aufgabe. Wer Beiträge datiert in Übersichten oder Archiven referenziert, sollte vorher wissen, dass die alten Zeiten stehen bleiben und ab dann einen anderen Bezug haben als die neuen. Es ist dieselbe Art von stiller Nebenwirkung, über die ich schon beim Aufräumen der SEO-Fehler im eigenen Blog gestolpert bin: Eine Einstellung ändern ist nie nur eine Einstellung ändern.
Solange ich die Umstellung nicht gemacht habe, ist meine Antwort nicht Warten, sondern Umrechnen. Ich setze date_gmt und weiß, was ich tue. Das ist die unangenehmere, aber ehrlichere Variante.
WP-Cron: warum die Uhr nicht die Uhr ist
Angenommen, die Zeitzone stimmt und der Zeitstempel stimmt. Dann bleibt die dritte Annahme, und sie ist die, die die wenigsten auf dem Schirm haben: dass zum gesetzten Zeitpunkt überhaupt jemand nachsieht.
Ausgelöst wird beim Seitenaufruf, nicht von einer Uhr
Das Plugin-Handbuch auf developer.wordpress.org ist an dieser Stelle unmissverständlich: WP-Cron laufe nicht dauerhaft wie der System-Cron, sondern werde nur beim Seitenaufruf ausgelöst. Es funktioniere so, dass bei jedem Seitenaufruf eine Liste geplanter Aufgaben daraufhin geprüft werde, was auszuführen ist. Als Beispiel für den Fehlerfall nennt das Handbuch genau die Situation, um die es hier geht: Wenn du eine Aufgabe auf 14 Uhr planst und bis 17 Uhr niemand eine Seite aufruft, kommt es zu Abweichungen im Zeitplan.
Das ist der Kern. Auf einer Seite ohne Besucher kann ein Beitrag verspätet erscheinen — nicht weil etwas kaputt ist, sondern weil der Auslöser fehlt. Das Handbuch nennt dazu auch die Kehrseite als Vorteil: Alle geplanten Aufgaben landen in einer Warteschlange und laufen bei der nächsten Gelegenheit, also beim nächsten Seitenaufruf. Verloren geht nichts. Nur pünktlich ist es eben nicht.
Echter Systemcron — und der Hinweis Missed schedule
Für den Fall, dass dir das zu unzuverlässig ist, beschreibt das Handbuch den Weg, WP-Cron in den Aufgabenplaner des Systems einzuhängen. Zuerst verhinderst du in der wp-config.php, dass WP-Cron beim Seitenaufruf angestoßen wird. Abgeschaltet ist damit nur dieser Auslöser — die Datei wp-cron.php bleibt aufrufbar, sie wird nur nicht mehr aus dem Seitenaufruf heraus gestartet:
define( 'DISABLE_WP_CRON', true );
Danach ruft der Systemcron die Datei wp-cron.php selbst auf. Das Handbuch gibt für Linux und macOS diesen Aufruf und diesen Crontab-Eintrag an — im Beispiel täglich um Mitternacht:
wget --delete-after https://YOUR_SITE_URL/wp-cron.php
0 0 * * * wget --delete-after https://YOUR_SITE_URL/wp-cron.php
Für Windows nennt das Handbuch den entsprechenden PowerShell-Aufruf powershell "Invoke-WebRequest https://YOUR_SITE_URL/wp-cron.php". Wichtig ist die Einordnung: Das Intervall im Beispiel ist täglich. Wer damit Beiträge auf die Minute veröffentlichen will, braucht ein deutlich engeres Intervall — sonst hat er die Unzuverlässigkeit nur von der Besucherzahl auf die Crontab-Zeile verschoben.
Und wenn es doch schiefgeht, hat WordPress dafür eine sichtbare Markierung. Im Kern prüft die Beitragsliste, ob ein Beitrag noch auf future steht, obwohl der geplante Zeitpunkt vorbei ist; trifft das zu, schreibt sie in die Datumsspalte den Hinweis Missed schedule, sinngemäß: verpasster Zeitplan. Ein eigener Beitragsstatus ist das ausdrücklich nicht — registriert sind auf dieser Installation nur publish, future, draft, pending, private und trash. Es ist ein Anzeigetext in der Liste, nicht ein Zustand des Beitrags. Die üblichen Ursachen dahinter sind genau die aus diesem Kapitel: kein Seitenaufruf zum passenden Zeitpunkt, ein abgeschaltetes WP-Cron ohne funktionierenden Ersatz, oder ein Aufruf von wp-cron.php, der nicht durchkommt.
Was ich seitdem praktisch tue
Aus dem Fall ist bei mir eine kurze Routine geworden. Sie kostet pro Beitrag vielleicht eine Minute und hat den Vorteil, dass sie die drei Annahmen einzeln abklopft, statt auf das Gesamtgefühl zu vertrauen.
Die Reihenfolge, die ich mir angewöhnt habe
- Zeitzone bewusst setzen. Einstellungen → Allgemein aufrufen, den Wert ansehen und entscheiden — Berlin eintragen oder bewusst bei UTC bleiben. Beides ist vertretbar, ein leeres Feld aus Versehen ist es nicht.
- Beim Terminieren über die Schnittstelle
date_gmtverwenden, zusammen mitstatus: future. Der Termin ist dann unabhängig davon richtig, was in der Einstellung steht. - Nach dem gesetzten Termin einmal nachsehen, ob der Beitrag wirklich erschienen ist. Nicht das Backend fragen, sondern die Startseite im ausgeloggten Zustand aufrufen. Steht der Beitrag noch auf „Geplant“, war es der Auslöser.
- Bei wiederholten Verspätungen den Auslöser ersetzen, statt am Zeitstempel zu drehen. Erst dann lohnt der Weg über
DISABLE_WP_CRONund einen echten Systemcron.
Punkt drei ist der, den ich am längsten unterschätzt habe. Ein Blick auf die eigene Startseite ist unspektakulär, aber er ist die einzige Prüfung, die alle drei Annahmen gleichzeitig testet. Wenn der Beitrag da ist, hat die Kette gehalten. Ich habe das mittlerweile in meiner Liste der Werkzeuge fürs Bloggen stehen, direkt neben den Dingen, die man einmal einrichtet und dann vergisst.
Die Kette aus drei Annahmen
Das ist die Lehre, die den ganzen Fall trägt. Terminierung fühlt sich nach einer Uhr an. Tatsächlich ist sie eine Kette aus drei Gliedern: einer Zeitzoneneinstellung, die im Zweifel leer ist; einem gespeicherten Zeitstempel, der je nach Feld unterschiedlich interpretiert wird; und einem Auslöser, der zufällig vorbeikommt. Jedes dieser Glieder kann still danebenliegen, und keines meldet sich von selbst. Die Uhrzeit im Editor sieht in allen drei Fehlerfällen völlig unauffällig aus.
Das ist derselbe Fehlertyp, dem ich beim Formular ohne form-Tag begegnet bin: Etwas sieht vollständig aus, weil das eine fehlende Teil unsichtbar ist. Bei terminierten Beiträgen hilft dagegen nur, die drei Glieder einmal einzeln anzufassen — und danach dem Ergebnis zu misstrauen, bis man es auf der eigenen Seite gesehen hat.
Nachtrag vom 28. August 2026: umgestellt — und einmal gestolpert
Nach dem Schreiben dieses Beitrags habe ich die Zeitzone auf Europe/Berlin gesetzt. Alles, was oben unter „Stand August 2026″ steht, beschreibt also den Zustand davor. Passiert ist genau das, was der Abschnitt zur Umstellung vorhersagt — und es ist trotzdem lehrreich, es einmal an den eigenen Zahlen zu sehen.
Zum Zeitpunkt der Umstellung standen sechzehn Beiträge auf „geplant“, alle auf sieben Uhr. Diese sieben Uhr war UTC, weil in UTC gerechnet wurde. Nach dem Umstellen war der gespeicherte lokale Zeitstempel unverändert sieben Uhr — jetzt aber als Berliner Zeit zu lesen, während die GMT-Angabe weiterhin auf sieben Uhr UTC stand. Beide Felder sagten damit Verschiedenes: die Liste zeigte sieben Uhr, erschienen wären die Beiträge um neun.
Der tatsächliche Erscheinungszeitpunkt hätte sich dabei nicht verschoben, weil die GMT-Angabe die maßgebliche ist. Falsch geworden wäre nur die Anzeige — die unauffälligste Art von Fehler. Ich habe deshalb alle sechzehn auf neun Uhr Ortszeit gezogen; die GMT-Angabe blieb dabei bei sieben Uhr, das Erscheinen also unverändert. Danach stimmen Anzeige und Wirklichkeit wieder überein.
Die Lehre daraus in einem Satz: Die Umstellung selbst dauert zehn Sekunden, das Nachziehen der Termine dauert länger — und wer sie vergisst, hat keinen Fehler, der auffällt, sondern eine Liste, die etwas anderes behauptet als die Wirklichkeit.


Schreibe einen Kommentar