WordPress ломает время (и как его чинить)

A presentation at WordPress Kyiv Meetup 2019–02 in February 2019 in Kyiv, Ukraine, 02000 by Andrey Savchenko

Slide 1

Slide 1

WP ломает время и как его чинить

Slide 2

Slide 2

2 Андрей «Rarst» Савченко — Rarst.net — WP контрактор — 1 Гс возраст — 336 Мс WP — за Date/Time в ядре

Slide 3

Slide 3

3 Вы когда–нибудь… меняли часовой пояс? Настройки → Общие → Часовой пояс

Slide 4

Slide 4

4 Вы когда–нибудь… локализовывали время? date_i18n() , the_date() , и т.д.

Slide 5

Slide 5

5 Очень краткая история времени 1. солнечное время 2. городское время 3. железнодорожное время 4. часовые пояся 5. всемирное координированное время (UTC)

Slide 6

Slide 6

6 Unix время 1 550 923 200 секунд от 1970–01–01 00:00:00 UTC

Slide 7

Slide 7

7 Unix время — последовательно — дружелюбно к хранению — дружелюбно к сравнению — не читаемо людьми

Slide 8

Slide 8

8 PHP DateTime $dt = new DateTime(); echo $dt->getTimestamp(); 1550923200 echo $dt->format( DATE_RFC3339 ); 2019-02-23T14:00:00+02:00 echo $dt->getTimezone()->getName(); Europe/Kiev php.net/datetime

Slide 9

Slide 9

9 PHP DateTime — основано на UTC — форматирование — разбор — английский язык php.net/datetime

Slide 10

Slide 10

10 phpdatebook.com

Slide 11

Slide 11

Slide 12

Slide 12

12 WP время — PHP 4 код — частичный PHP 5 ретрофит — собственная логика часовых поясов — собственная интернационализация

Slide 13

Slide 13

13 WpDateTime — наследует PHP DateTime классы — обходит баги WP — разбирает WP данные github.com/Rarst/wpdatetime

Slide 14

Slide 14

14 wp_date (в процессе…) — аудит и исправления багов ядра — объединенная обработка часового пояса — настоящие таймштампы — каноническое UTC github.com/Rarst/wp-date

Slide 15

Slide 15

15 Настройка часового пояса WP настройка gmt_offset timezone_string Киев 2 ‘Europe/Kiev’ UTC+2 ‘2’ ” #44985

Slide 16

Slide 16

16 Часовой пояс WP во всех случаях 1. прочитать timezone_string 2. если пусто — прочитать gmt_offset 3. конвертировать число в формат ±00:00 (PHP 5.5+)

Slide 17

Slide 17

17 WpDateTimeZone для разбора пояса $timezone = WpDateTimeZone::getWpTimezone(); настройка $timezone->getName() Киев ‘Europe/Kiev’ UTC+2 ‘+02:00’ С надеждой в wp_date: wp_timezone()

Slide 18

Slide 18

18 date_i18n() DateTime date() date_i18n() язык английский английский текущий WP часовой пояс произвольный текущий PHP текущий WP ввод произвольный таймштамп «WP таймштамп» формат date() date() date(), неполный developer.wordpress.org/reference/functions/date_i18n С надеждой в wp_date: wp_date()

Slide 19

Slide 19

19

Slide 20

Slide 20

20 Логика date_i18n() echo date_i18n( ‘Y, F, j, G:i T’ ); 1. Y, F , j, G:i T 2. Y, Февраль , j, G:i T — текущий язык 3. Y, Февраль, j, G:i \E\E\T — часовой пояс 4. 2019, Февраль, 23, 14:00 EET — date()

Slide 21

Slide 21

21 date_i18n() ломается с Unix временем echo date( DATE_RFC3339, time() ); 2019-02-23T12:00:00+00:00 echo date_i18n( DATE_RFC3339, time() ); 2019-02-23T12:00:00+02:00 #38771

Slide 22

Slide 22

22 post_date post_date post_date_gmt post_title 2019-02-23 12:00:00 2019-02-23 12:00:00 Запись в Лондоне WP настроен на часовой пояс Лондон: the_date( DATE_RFC3339 ); 2019-02-23T12:00:00+00:00

Slide 23

Slide 23

23 post_date ломается при смене пояса post_date post_date_gmt post_title 2019-02-23 12:00:00 2019-02-23 12:00:00 Запись в Лондоне WP настроен на часовой пояс Киев: the_date( DATE_RFC3339 ); 2019-02-23T12:00:00+02:00 #38774

Slide 24

Slide 24

24 post_date во всех случаях 1. прочитать post_date_gmt 2. если пусто — прочитать post_date 3. прочитать часовой пояс WP 4. перевести post_date[_gmt] в часовой пояс 5. перевести в нужный формат

Slide 25

Slide 25

25 WpDateTime для разбора даты записи post_date post_date_gmt post_title 2019-02-23 12:00:00 2019-02-23 12:00:00 Запись в Лондоне WP настроен на часовой пояс Киев: $time = WpDateTime::createFromPost( get_post() ); echo $time->formatI18n( DATE_RFC3339 ); 2019-02-23T14:00:00+02:00 С надеждой в wp_date: каноническое UTC.

Slide 26

Slide 26

26 Выводы — WP неправильно и хранит и выводит время — читаем UTC; пишем таймштамп, UTC, RFC 3339 — используем DateTime для расчетов — используем WpDateTime для интеграции — надеемся wp_date выйдет

Slide 27

Slide 27

27 Спасибо за ваше время! Вопросы? twitter.com/Rarst wpua.slack.com wordpress.slack.com/messages/core-datetime Rarst.net/slides/time-kiev

Slide 28

Slide 28

28 Использованные изображения — Фото Adina Voicu CC0 — Фото Eugene Shelestov CC0