WordPress breaks time (and how to fix it)

Andrey “Rarst” Savchenko, WordCamp Bucharest 2018

Old man watch

WP breaks time & how to fix it

Andrey “Rarst” Savchenko

Had you ever...

changed WP time zone?

Settings → General → Timezone

Had you ever...

output localized time?

date_i18n(), the_date(), etc.

Time is an illusion

A very brief history of time

  1. solar time
  2. city time
  3. rail time
  4. time zones
  5. Universal Coordinated Time

Unix time

1 540 645 200

seconds since 1970–01–01 00:00:00 UTC

Unix time

PHP DateTime

$dt = new DateTime();
echo $dt->getTimestamp();
1540645200
echo $dt->formatDATE_RFC3339 );
2018-10-27T16:00:00+03:00
echo $dt->getTimezone()->getName();
Europe/Bucharest
php.net/datetime

PHP DateTime

php.net/datetime
PHP Date Book phpdatebook.com
Time on fire

WP time

WpDateTime

github.com/Rarst/wpdatetime

wp_date (work in progress...)

github.com/Rarst/wp-date

WP time zone options

settinggmt_offsettimezone_string
Bucharest3'Europe/Bucharest'
UTC+3'3'''
#44985

WP time zone in all cases

  1. get timezone_string
  2. if empty — get gmt_offset
  3. convert the offset number to ±00:00 (PHP 5.5+)

WpDateTimeZone to parse time zone

$timezone WpDateTimeZone::getWpTimezone();
setting$timezone->getName()
Bucharest'Europe/Bucharest'
UTC+3'+03:00'

Hopefully in wp_date: wp_timezone()

date_i18n()

DateTime date() date_i18n()
language English English WP locale
time zone arbitrary current PHP current WP
input arbitrary timestamp “WP timestamp”
formats date() date() date(), incomplete
developer.wordpress.org/reference/functions/date_i18n

Hopefully in wp_date: wp_date()

Graph of WP Date/Time API calls

date_i18n() logic

echo date_i18n'j F Y, \o\r\a G:i T' );
  1. j F Y, \o\r\a G:i T
  2. j \o\c\t\o\m\b\r\i\e Y, \o\r\a G:i T — locale
  3. j \o\c\t\o\m\b\r\i\e Y, \o\r\a G:i \E\E\S\T — zone
  4. 27 octombrie 2018, ora 16:00 EEST — date()

date_i18n() fails w/ Unix timestamp

echo dateDATE_RFC3339time() );
2018-10-27T13:00:00+00:00
echo date_i18nDATE_RFC3339time() ); 2018-10-27T13:00:00+03:00
#38771

post_date

post_datepost_date_gmtpost_title
2018-10-27 14:00:00 2018-10-27 13:00:00 A post made in London
WP set to London time zone:
the_dateDATE_RFC3339 );
2018-10-27T14:00:00+01:00

post_date fails w/ changed time zone

post_datepost_date_gmtpost_title
2018-10-27 14:00:00 2018-10-27 13:00:00 A post made in London
WP set to Bucharest time zone:
the_dateDATE_RFC3339 );
2018-10-27T14:00:00+03:00
#38774

post_date in all cases

  1. get post_date_gmt
  2. if empty — get post_date
  3. get WP time zone
  4. adjust post_date[_gmt] with the time zone
  5. convert to desired format

WpDateTime to parse post date

post_datepost_date_gmtpost_title
2018-10-27 14:00:00 2018-10-27 13:00:00 A post made in London
WP set to Bucharest time zone:
$time WpDateTime::createFromPostget_post() );
echo $time->formatI18nDATE_RFC3339 );
2018-10-27T16:00:00+03:00

Hopefully in wp_date: canonical UTC.

Takeaways

Thank you for your time! Questions?

twitter.com/Rarst
wordpress.slack.com/messages/core-datetime



Rarst.net/slides/time-buc

Image credits