当使用‘c’时间格式时,为什么时间函数显示无效时区?

时间:2012-06-09 作者:its_me

这些是我在主题中用来显示“entry meta”的函数,其中包括publishedlast modified 文章日期(除其他外):

// 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. 知道为什么吗?

3 个回复
最合适的回答,由SO网友:Rarst 整理而成

问题是,为了获得正确的输出,WP需要通过date_i18n() 作用使用日期格式时,hardcoded in PHP code (不仅仅是保存在PHP中DATE_* 常量)like\'c\' - 它不可用于您的代码,因此可湿性粉剂处理。

系统范围内的解决方案是使用类似的格式重新处理日期can 可通过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;
}

SO网友:its_me

(无需担心,请按照上面更好的答案进行操作。Please do NOT edit this answer. 它作为参考存在。)

大多数WordPress主题和插件(尤其是受尊敬的开发人员开发的主题和插件)都使用c 常量,它以与此相同的格式输出时间戳:2012-06-14T10:32:11-00:00.

例如,<?php get_the_date( \'c\' ) ?> 将输出如下内容2012-06-14T10:32:11-00:00.

起初,我认为这是他们所有人的轻率决定,但后来我了解到这是一种时间戳格式recommended by the World Wide Web Consortium, 并且有自己预定义的日期常量DATE_W3C. 没有问题了,句号。

WordPress中的问题例如WordPress Dashboard > Settings > General 我设置了TimezoneNew York.

现在,这个代码<?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的差值is NOT. 这不是个小问题,时间不对!

解决方案首先,我更改了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 plugin\'s 例如,打开图形功能)。这是不可行的。所以,我开始寻找替代品。

感谢examples in the PHP Manual functions reference for Date/Time, 我意识到我可能会在函数中用类似的东西覆盖WordPress的时区设置。php(在第一个<?php):

date_default_timezone_set(\'America/New_York\');
瞧!get_the_date( \'c\' );get_the_modified_date( \'c\' ); 现在开始显示正确的日期、时间和时区偏移!一次改变就可以统治所有人!

其他链接

List of Supported Timezones in PHP

  • WordPress Codex: Formatting Date and Time


    • 预编辑使用Y-m-d\\TH:i:sP 而不是c -- 时间戳格式保持不变,但它显示正确的时区偏移量。

      这个PHP Date() Cheatsheat 非常有帮助

    SO网友:Stephen Harris

    WordPress自动将服务器的PHP时区设置为GMT。这是为了使任何日期操作保持一致,如果更改,可能会导致一些错误。

    这意味着任何本机函数date 将任何日期解释为GMT(或UTC)格式。类似地DateTime 对象将为UTC。

    您不应该真正改变这一点,因为这可能会产生意外的后果。

    问题

    使用的问题,比如get_the_modified_date( \'c\' ) 它得到的日期时间(比如2012年6月14日11:55:00)引用了博客时区中的修改日期。使用“c”格式化日期时,假定上述日期时间在UTC时区内。

    If using any format which (unlike \'c\') doesn\'t include the timezone then you should be fine. (顺便说一下,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

    结束

    相关推荐

    列出分类法:如果分类法没有POST,就不要列出分类法--取决于定制的POST-META?

    这可能很难解释,我不知道是否有解决办法!?我有一个名为“wr\\u event”的自定义帖子类型和一个名为“event\\u type”的分层自定义分类法。自定义帖子类型有一个元框,用于event_date 并且与此帖子类型关联的所有帖子都按以下方式排序event_date. 我在循环中有一个特殊的条件来查询event_date 已经发生了-在这种情况下,它没有显示,但只列在我的档案中。就像你可以使用wp_list_categories() 我编写了一个自定义函数,它以完全相同的方式列出所有分类术语。现在