WordPress breaks time (and how to fix it)

A presentation at WordCamp Bucharest 2018 in October 2018 in Bucharest, Romania by Andrey Savchenko

Slide 1

Slide 1

WP breaks time & how to fix it

Slide 2

Slide 2

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

Slide 3

Slide 3

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

Slide 4

Slide 4

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

Slide 5

Slide 5

5

Slide 6

Slide 6

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

Slide 7

Slide 7

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

Slide 8

Slide 8

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

Slide 9

Slide 9

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

Slide 10

Slide 10

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

Slide 11

Slide 11

11 phpdatebook.com

Slide 12

Slide 12

Slide 13

Slide 13

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

Slide 14

Slide 14

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

Slide 15

Slide 15

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

Slide 16

Slide 16

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

Slide 17

Slide 17

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

Slide 18

Slide 18

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

Slide 19

Slide 19

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

Slide 20

Slide 20

20

Slide 21

Slide 21

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

Slide 22

Slide 22

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

Slide 23

Slide 23

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

Slide 24

Slide 24

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

Slide 25

Slide 25

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

Slide 26

Slide 26

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.

Slide 27

Slide 27

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

Slide 28

Slide 28

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

Slide 29

Slide 29

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