Why times appear wrong.
THE COMMON CONFUSION
Times displaying offset by hours from what you expect.
WHERE TIMEZONES ARE SET
The server's timezone The database's timezone PHP's timezone setting The application's own timezone setting
Four places, and they need to agree or at least be understood.
DATETIME VERSUS TIMESTAMP
DATETIME stores what you put in, unchanged.
TIMESTAMP is converted to UTC on storage and back on retrieval, using the session timezone. That conversion is what produces surprises.
IN WORDPRESS
WordPress stores post times in both local and GMT columns, and uses the timezone set in the general settings.
Changing the timezone setting does not retroactively change stored times.
THE PRACTICAL ADVICE
Set the application's timezone correctly and let it handle conversion.
Do not attempt to compensate by adjusting stored values.
AFTER A MIGRATION
Check that the PHP timezone matches what the application expects. A mismatch shifts every displayed time.
CHECKING
SELECT NOW(); shows the database's current time.