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


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

// 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 летнего времени) в Панель управления WordPress > Настройки> Общие , выводимая временная метка показывает GMT+00:00. Есть идеи, почему?

Author: Rarst, 2012-06-09

3 answers

Проблема в том, что для правильного вывода WP необходимо обработать дату через date_i18n() функция. Когда вы используете формат даты , жестко закодированный в PHP-коде (а не просто сохраненный в PHP DATE_* константа), как '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;
}
 4
Author: Rarst, 2013-01-07 13:43:09

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 на часовой пояс вашего блога, а затем снова переключиться. Но это не здорово. Вместо этого используйте объект PHP DateTime. Объект PHP datetime будет иметь часовой пояс, установленный в 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

 2
Author: Stephen Harris, 2012-06-15 11:50:52

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

Ситуация

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

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

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

Проблемы В WordPress

Скажем, например, что в Панель управления WordPress > Настройки> Общие Я установил Часовой пояс на Нью-Йорк.

Теперь этот код <?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. Но смещение часового пояса, т.Е. разница с GMT/UTC , НЕ . Это не маленькая проблема, сейчас НЕПОДХОДЯЩЕЕ время!

Решение

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

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

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

date_default_timezone_set('America/New_York');

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

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


Предварительное редактирование

Используйте Y-m-d\TH:i:sP вместо c -- формат метки времени остается прежним, но он показывает правильное смещение часового пояса.

Эта Дата PHP() Читшит был очень полезен.

 2
Author: its_me, 2012-06-16 11:39:29