A server whose clock has drifted produces errors that look like anything but a clock: certificates that are "not yet valid", logins that fail with a correct password, cron jobs at the wrong hour. It is worth ruling out early because it takes one command.
timedatectl
Turn on synchronisation
timedatectl set-ntp true\ntimedatectl show -p NTPSynchronized --value
Three clocks, three settings
- The system - keep it on UTC. Every log and every stored timestamp is then unambiguous.
- PHP - date.timezone, which affects what date() prints and nothing else.
- MySQL - its own time_zone, which affects NOW() and CURRENT_TIMESTAMP.
date
php -r 'echo date("Y-m-d H:i:s T"), PHP_EOL;'
mysql -e "SELECT NOW(), @@global.time_zone, @@session.time_zone;"
If PHP writes a timestamp in local time and MySQL stores in UTC, every comparison is out by the offset - and only twice a year, when the offset changes, does anyone notice. Store UTC, convert on display.
What breaks when the clock is out
- TLS. A certificate valid from tomorrow is refused today. The browser error names the certificate, not the clock.
- Tokens and two-factor. A TOTP code is derived from the time; more than thirty seconds out and every code is wrong.
- Cron. Jobs run at the wrong hour, or twice, or not at all across a change.
- Correlating logs. Two servers minutes apart cannot be read together at all.
Set the system to UTC and never change it. Show local time to people at the last possible moment - in the browser, from their own clock.