Als je ooit een bericht live hebt gezet, om het vervolgens op de publieke site te zien staan met het label "57 jaar geleden", terwijl je dashboard rustig volhoudt dat het tien minuten over het uur is geplaatst, dan ken je de specifieke pijn van deze bug. Het breekt de lay-out niet. Het veroorzaakt geen fatale fout. Het veroudert je content simpelweg met een halve eeuw, en naar je thema-bestanden staren zal het getal niet veranderen.
Dit probleem overleeft meestal de gebruikelijke controles. Je doorzoekt met grep single.php, archive.php en functions.php op zoek naar een foutieve get_the_date()-aanroep. Alles ziet er standaard uit. Je ververst de live pagina. De geest van 1968 spookt nog steeds door je auteursregel. Op dat punt heeft het probleem bijna niets te maken met je templates en alles met de manier waarop tijd door de WordPress-stack stroomt.
Waarom dat specifieke getal steeds blijft verschijnen
Het getal "57 jaar geleden" is niet willekeurig. WordPress-thema's tonen vaak relatieve tijd via de human_time_diff()-functie, die de tijdstempel van een bericht vergelijkt met het huidige moment en een vriendelijke tekst print zoals "2 uur geleden". Om die berekening te laten werken, heeft PHP een geldige Unix-tijdstempel nodig — een telling van seconden sinds 1 januari 1970, de Unix-epoch.
Wanneer iets de tijdstempel verwijdert of corrumpeert voordat deze de berekening bereikt, eindigt de functie vaak met het vergelijken van nul (of een vergelijkbaar ongeldig startpunt) met het nu. Het resultaat is een tijdsspanne die ongeveer vijfënhalf decennium teruggaat, die telkens één kalenderjaar vooruit kruipt. Het is een symptoom van een ontbrekende of verkeerd gelezen tijdwaarde, niet van een database vol retro-blogposts.
De misleiding van het dashboard
Een van de frustrerende aspecten van deze bug is de gespleten persoonlijkheid van je beheerderspaneel. Binnen wp-admin toont de lijst met berichten de juiste publicatiedatum, omdat WordPress deze vaak rechtstreeks uit de MySQL wp_posts-tabel haalt en deze aan de serverzijde formatteert zonder deze door de relatieve-tijdfilter te halen. De frontend kan echter vertrouwen op een thema of plugin die human_time_diff() aanroept, of het kan de ruwe database-waarde door een keten van PHP-tijdzoneconversies sturen die de backend volledig omzeilt.
De gegevens zijn dus meestal nog intact. Het is de pijplijn tussen de database en de gerenderde HTML die een knik vertoont.
PHP-versie en tijdzone-instellingen
Begin bij PHP. Hostingpanels laten versie-wisselingen onschuldig lijken, maar PHP gaat anders om met tijdobjecten bij verschillende grote releases. Een site die legacy PHP 7.4-code draait op een plotselinge PHP 8.1-omgeving, kan subtiele verschuivingen ervaren in de manier waarop DateTime-objecten lege of foutieve strings initialiseren. Als je php.ini-bestand date.timezone ongedefinieerd laat, valt PHP terug op UTC en gaat ervan uit dat de server het beste weet. WordPress kan het daar niet mee eens zijn.
Controleer of iemand een tijdzone-verklaring hardcoded heeft in wp-config.php. Een regel als date_default_timezone_set( 'Asia/Kolkata' ); lijkt nuttig, maar WordPress verwacht zijn eigen klok te beheren via de waarde die is ingesteld onder Instellingen > Algemeen. Het forceren van een offset op PHP-niveau kan een raceconditie creëren waarbij de core gelooft dat de tijd lokaal is en PHP gelooft dat deze universeel is. Wanneer deze offsets botsen tijdens een tijdstempelconversie, kan het resultaat dat naar je template wordt teruggestuurd naar nul instorten.
Server-tijdzoneconfiguraties
Je MySQL-server heeft zijn eigen idee van lokale tijd. WordPress schrijft twee datums voor elk bericht: post_date in de lokale tijd van de site, en post_date_gmt in de universele tijd. Als de globale time_zone van de database verandert — bijvoorbeeld van SYSTEM naar +00:00 na een migratie — kan strtotime() van PHP er niet in slagen de opgeslagen string te verzoenen met wat het verwacht. De database slaat nog steeds 2024-03-15 14:30:00 op, maar de context eromheen verschuift, en de geparseerde output wordt false of null in PHP.
Praktijkvoorbeeld: een managed host verplaatst je database van een node die MySQL 5.7 draait met SYSTEM-tijd naar een cluster die MariaDB 10.11 draait ingesteld op strikte UTC. Je thema verandert nooit. Je WordPress-instellingen veranderen nooit. Toch geeft get_the_time( 'U' ) — het Unix-tijdstempelformaat — plotseling een lege waarde terug voor sommige berichten, en valt de relatieve-tijdfunctie terug op die epoch-nul-berekening. De oplossing is het afstemmen van de applicatie-tijdzone, de database-tijdzone en de klok van het besturingssysteem, zodat WordPress niet hoeft te raden welke referentiekader het moet gebruiken.
Database-tijdstempelformaten
WordPress core stores post dates in MySQL DATETIME columns, not TIMESTAMP fields. That distinction matters because DATETIME holds a calendar value without_zone awareness in older MySQL versions, whereas TIMESTAMP converts everything to UTC behind the scenes. If a plugin or migration tool has altered your wp_posts schema, or if an old backup restored invalid zero dates into the table, WordPress may read a value like 0000-00-00 00:00:00 and quietly hand it off to your theme.
Modern MySQL modes, particularly NO_ZERO_DATE and STRICT_TRANS_TABLES, reject those zero placeholders. If a backup script inserted them during a migration, the database might have truncated or nulled them on import. You can verify this quickly with a direct SQL query:
SELECT ID, post_title, post_date, post_date_gmt
FROM wp_posts
WHERE post_status = 'publish'
ORDER BY post_date DESC
LIMIT 10;
If the raw columns look correct but the site still displays ancient history, the corruption is happening after the query. If the columns themselves contain zeroes, you have found the leak in the plumbing.
Plugin Conflicts with Date Functions
Plugins that filter date output are common culprits. Multilingual tools such as WPML or Polylang hook into get_the_date to translate month names. Caching plugins intercept the final HTML. Either layer can accidentally pass an unformatted string into a function expecting a Unix integer.
A translation plugin might replace “March 15, 2024” with its localized equivalent, but if a theme then pipes that localized string into strtotime() inside a custom function, the parser fails on non-English characters and returns false. That false value hits human_time_diff(), which compares zero against now, producing the infamous half-century gap.
Object cache layers complicate this further. Redis or Memcached can store a serialized WP_Post object from a request that briefly failed to parse the date. Every subsequent visitor receives that corrupted object straight from RAM, bypassing the database entirely. The issue persists on the live site because your production stack has cache infrastructure that your local install lacks.
A Practical Debugging Checklist
Because the symptom hides deep in the stack, you need to peel layers systematically until the dates snap back into place.
- Query the database directly. Open phpMyAdmin or run WP-CLI and inspect the raw
post_datevalues. If they are correct, the database is not the problem. - Switch to a default theme. Activate Twenty Twenty-Four or Twenty Twenty-Three. If the bug disappears, audit your active theme and child theme for custom functions wrapping time output.
- Silence the plugins. Rename the
/wp-content/pluginsfolder temporarily, or disable all plugins from the dashboard. Re-enable them one by one, checking the frontend after each activation. - Read the error log. Look for timezone warnings,
DateTimeerrors, orstrtotime()complaints. They often point to the exact
