WP breaks time & how to fix it

2 Andrey “Rarst” Savchenko — Rarst.net — WP contractor — 1 Gs old — 325 Ms WP — Date/Time maintainer

3 Had you ever... changed WP time zone? Settings → General → Timezone

4 Had you ever... output localized time? date_i18n() , the_date() , etc.

5

6 A very brief history of time 1. solar time 2. city time 3. rail time 4. time zones 5. Universal Coordinated Time

7 Unix time 1 540 645 200 seconds since 1970–01–01 00:00:00 UTC

8 Unix time — consistent — storage–friendly — comparison–friendly — not human readable

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

10 PHP DateTime — UTC–based — formatting — parsing — primarily English php.net/datetime

11 phpdatebook.com

13 WP time — PHP 4 code — partial PHP 5 retrofit — custom time zone logic — custom internationalization

14 WpDateTime — extends PHP DateTime classes — works around WP bugs — parses WP data github.com/Rarst/wpdatetime

15 wp_date (work in progress...) — core bugs audit & fixes — unified timezone processing — real timestamps & canonical UTC github.com/Rarst/wp-date

16 WP time zone options setting gmt_offset timezone_string Bucharest 3 'Europe/Bucharest' UTC+3 '3' '' #44985

17 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+)

18 WpDateTimeZone to parse time zone $timezone = WpDateTimeZone::getWpTimezone(); setting $timezone->getName() Bucharest 'Europe/Bucharest' UTC+3 '+03:00' Hopefully in wp_date: wp_timezone()

19 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()

20

21 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()

22 date_i18n() fails w/ Unix timestamp echo date( DATE_RFC3339, time() ); 2018-10-27T13:00:00+00:00 echo date_i18n( DATE_RFC3339, time() ); 2018-10-27T13:00:00+03:00 #38771

23 post_date post_date post_date_gmt post_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_date( DATE_RFC3339 ); 2018-10-27T14:00:00+01:00

24 post_date fails w/ changed time zone post_date post_date_gmt post_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_date( DATE_RFC3339 ); 2018-10-27T14:00:00+03:00 #38774

25 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

26 WpDateTime to parse post date post_date post_date_gmt post_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::createFromPost( get_post() ); echo $time->formatI18n( DATE_RFC3339 ); 2018-10-27T16:00:00+03:00 Hopefully in wp_date: canonical UTC.

27 Takeaways — WP gets time storage and output wrong — read UTC time; write timestamp, UTC, or RFC 3339 — use DateTime to operate time — use WpDateTime to bridge WP and PHP — hope wp_date works out

28 Thank you for your time! Questions? twitter.com/Rarst wordpress.slack.com/messages/core-datetime Rarst.net/slides/time-buc

29 Image credits — Photo by Adina Voicu CC0 — “Time” comic by Zach Weinersmith — Photo by Eugene Shelestov CC0