Intereting Posts

Почему временные функции показывают недействительный часовой пояс при использовании формата времени «c»?

Это функции, которые я использую в своей теме, для отображения «entry-meta», которая включает опубликованные и последние измененные даты (среди других) статьи:

// Shows Author and Published Date if ( ! function_exists( 'reddle_posted_on' ) ) : function reddle_posted_on() { printf( __( '<span class="byline">Posted by <span class="author vcard"><a class="url fn n" href="%5$s" title="%6$s" rel="author">%7$s</a></span></span><span class="sep"> &mdash; </span><span class="entry-date"><time datetime="%3$s" pubdate>%4$s</time></span>', 'reddle' ), esc_url( get_permalink() ), esc_attr( get_the_time() ), esc_attr( get_the_date( 'c' ) ), esc_html( get_the_date() ), esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ), sprintf( esc_attr__( 'View all posts by %s', 'the-wolf' ), get_the_author() ), esc_html( get_the_author() ) ); } endif; // Shows Last Modified Date if ( ! function_exists( 'reddle_last_modified_on' ) ) : function reddle_last_modified_on() { printf( __( 'Last updated on <time class="updated" itemprop="dateModified" datetime="%2$s">%3$s</time>', 'reddle' ), esc_attr( get_the_modified_time() ), esc_attr( get_the_modified_date( 'c' ) ), esc_html( get_the_modified_date( 'F j, Y ~ H:i' ) ) ); } endif; 

Вы видите что-то не так с этими функциями? Проблема заключается в том, что, несмотря на установку часового пояса моего блога на GMT-05:00 (-04: 00 DST) в WordPress Dashboard> Settings> General , выводимая временная метка показывает GMT+00:00 . Любая идея почему?

Проблема заключается в том, что для корректного вывода WP необходимо обработать дату с помощью функции date_i18n() . Когда вы используете формат даты, жестко закодированный в PHP-коде (не просто сохраненный в PHP DATE_* constant), такой как 'c' он недоступен для вашего кода и поэтому для WP для обработки.

Общесистемное исправление будет состоять в том, чтобы повторно обрабатывать дату с аналогичным форматом, к которому может обращаться код WP:

 add_filter( 'date_i18n', 'fix_c_time_format', 10, 4 ); function fix_c_time_format( $date, $format, $timestamp, $gmt ) { if ( 'c' == $format ) $date = date_i18n( DATE_ISO8601, $timestamp, $gmt ); return $date; } 

WordPress автоматически устанавливает часовой пояс сервера в PHP на GMT. Это должно привести к тому, что любые манипуляции с датами согласованы – и, если они будут изменены, могут вызвать некоторые ошибки.

Это означает, что любые нативные функции, такие как date будут интерпретировать любую дату в формате GMT ​​(или UTC). Точно так же часовой пояс для объектов DateTime будет UTC.

Вы не должны действительно изменять это, поскольку это может иметь непреднамеренные последствия.

Проблема

Проблема с использованием, скажем get_the_modified_date( 'c' ) заключается в том, что дата-время, которое она получает (скажем, 2012-06-14 11:55:00 ), ссылается на измененную дату в часовом поясе блога. Когда дата формируется с использованием «c», предполагается, что указанное время датируется часовым поясом UTC.

Если вы используете какой-либо формат, который (в отличие от «c») не включает часовой пояс, тогда вы должны быть в порядке. (Временная метка unix, кстати, неявно ссылается на часовой пояс).

Как просмотреть даты в WordPress

Его лучшая практика для обработки всех дат в часовой пояс UTC, а затем только при их отображении, конвертируя их в ваш часовой пояс.

Решение

get_the_modified_date( 'c', true ) вместо этого гарантирует, что дата-время, которое она получает, фактически является датой, измененной в часовом поясе GMT ​​(UTC). Теперь, когда он формируется с помощью «c», он снова (но теперь правильно) предположил, что дата-время находится в часовом поясе UTC.

Использование разностного часового пояса

Вы можете установить часовой пояс PHP в часовой пояс вашего блога, а затем снова вернуться обратно. Но это не здорово. Вместо этого используйте объект DateTime PHP. Объект datetime PHP будет иметь часовой пояс, установленный для UTC, но это может быть явно чрезмерным в конструкции объекта:

 $timestamp = get_the_modified_date( 'u', true ); //Correct date-time object in UTC $date_obj = new DateTime("@$timestamp"); //Displays 2012-06-14T14:32:11-00:00 echo $date_obj->format('c'); //Correct date-time object now in America/New_York timezone $date_obj->setTimezone(new DateTimeZone('America/New_York')); //Displays 2012-06-14T10:32:11-04:00 echo $date_obj->format('c'); 

Если вы находитесь за объектом PHP DateTimeZone часового пояса своего блога, см. Эту статью: https://gist.github.com/2724520

(Nevermind, следуйте лучшим ответам выше. Пожалуйста, НЕ редактируйте этот ответ. Он существует как ссылка.)

Ситуация

В большинстве тем WordPress и плагинов (особенно для уважаемых разработчиков) используется константа c которая выводит временную метку в формате, идентичном этому: 2012-06-14T10:32:11-00:00 .

Например, <?php get_the_date( 'c' ) ?> что-то вроде этого 2012-06-14T10:32:11-00:00 .

Первоначально я думал, что это все-таки бездумное решение, но потом я узнал, что это формат временной отметки, рекомендованный консорциумом World Wide Web , и имеет собственную предопределенную постоянную дату DATE_W3C . Больше вопросов, времени.

Проблемы в WordPress

Скажем, например, что в WordPress Dashboard> Settings> General я установил Timezone в New York .

Теперь этот код <?php get_the_date( 'c' ) ?> В шаблоне (темы или плагины, как <?php get_the_date( 'c' ) ?> выше) выведет что-то вроде этого: 2012-06-14T10:32:11-00:00

См. Ошибку? Да, когда это ДОЛЖНО быть этим 2012-06-14T10:32:11 -04:00 WordPress выводит это 2012-06-14T10:32:11 -00:00

Это имеет место даже с темами и плагинами, разработанными основными разработчиками WordPress.

Дата и время абсолютно правильные, по часовой America/New_York которая является America/New_York . Но смещение временной зоны, т. Е. Разница с GMT / UTC , НЕ . Это не маленькая проблема, это НЕПРАВИЛЬНОЕ время!

Решение

Сначала я изменил все экземпляры get_the_date( 'c' ); и get_the_modified_date( 'c' ); get_the_date( 'Ymd\TH:i:sP' ); и get_the_modified_date( 'Ymd\TH:i:sP' ); соответственно, и это, казалось, решило проблему (т. е. показало правильное смещение).

Реальная проблема заключалась в том, что я понял, что мне придется внести эти изменения в несколько плагинов, которые я использую (да, они выводят метки времени, например, функцию открытого графика плагина Facebook ). Это нежизнеспособно. Итак, я начал искать альтернативы.

Благодаря примерам в справочнике по функциям PHP Manual для Date / Time я понял, что я мог бы переопределить настройку Timezone WordPress с помощью чего-то вроде этого в functions.php (сразу после первого <?php ):

 date_default_timezone_set('America/New_York'); 

И вуаля! get_the_date( 'c' ); и get_the_modified_date( 'c' ); теперь начали показывать правильную дату, время и часовой пояс! Одно изменение, чтобы править ими всем!

Другие ссылки

  • Список поддерживаемых часовых поясов в PHP

  • WordPress Codex: форматирование даты и времени


Pre-Edit

Использовать Ymd\TH:i:sP вместо формата c timestamp остается неизменным, но он показывает правильное смещение часового пояса.

Этот PHP Date () Cheatsheat был очень полезен.