Почему функции времени показывают недопустимый часовой пояс при использовании формата времени "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"> — </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
. Есть идеи, почему?
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;
}
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
( Неважно, следуйте лучшим ответам выше. Пожалуйста, не редактируйте этот ответ. Он существует как ссылка.)
Ситуация
Большинство тем и плагинов 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() Читшит был очень полезен.