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

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

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

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

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

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

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

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

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

10 phpdatebook.com

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

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

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

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

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

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

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

19

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

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

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

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

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

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.

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

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

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