Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

These are the functions I use in my theme to display the "entry-meta" which includes published and last modified dates (among others) of an article:

// 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;

Do you see anything wrong with these functions? The problem is, despite setting the time zone of my blog to GMT-05:00 (-04:00 DST) in WordPress Dashboard > Settings > General the timestamp that is output shows GMT+00:00. Any idea why?

share|improve this question

3 Answers 3

up vote 3 down vote accepted

The issue is that for correct output WP needs to process date through date_i18n() function. When you use date format, hardcoded in PHP code (not simply saved in PHP DATE_* constant) like 'c' - it's not available to your code and so for WP to process.

System-wide fix would be to re-process date with analogous format that can be accessed by WP code:

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;
}
share|improve this answer

WordPress automatically sets the server's timezone in PHP to GMT. This is to make any date manipulations consistent - and if changed, can cause some errors.

This means any native functions like date will interpret any date to be in the GMT (or UTC) format. Similarly the timezone for DateTime objects will be UTC.

You should not really change this, as this may have unintended consequences.

The problem

The problem with using, say get_the_modified_date( 'c' ) is that the date-time it gets (say 2012-06-14 11:55:00) references the modified date in the blog's timezone. When the date is formated using the 'c' - it is assumed that the above date-time is in the UTC timezone.

If using any format which (unlike 'c') doesn't include the timezone then you should be fine. (A unix timestamp, by the way, does implicitly reference a timezone).

How to view dates in WordPress

Its best practise to treat all dates in the UTC timezone and then only when displaying them, converting them to your local timezone.

The solution

get_the_modified_date( 'c', true ) instead ensures that the date-time it gets is in fact the date modified in the GMT (UTC) timezone. Now when it is formed using 'c', it is again (but now correctly so) assumed that the date-time is in the UTC timezone.

Using a differenct timezone

You could set PHP's timezone to your blog's timezone and then switch back again. But this isn't great. Instead, make use of PHP's DateTime object. A PHP datetime object will have timezone set to UTC, but this can be explicitly over-ridden in the construction of the object:

$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');

If you are after the PHP DateTimeZone object of your blog's timezone, see this gist: https://gist.github.com/2724520

share|improve this answer
1  
Sensible answer. An alternative would be to use something else, other than c like Y-m-d\TH:i:sP as in get_the_date( 'Y-m-d\TH:i:sP' ); -- or -- DATE_W3C as in get_the_date( DATE_W3C ); –  its_me Jun 15 '12 at 12:24

(Nevermind, follow the better answers above. Please do NOT edit this answer. It exists as a reference.)

The Situation

Most of the WordPress themes and plugins (especially ones by esteemed developers) use the c constant which outputs the timestamp in a format identical to this: 2012-06-14T10:32:11-00:00.

For instance, <?php get_the_date( 'c' ) ?> would output something like this 2012-06-14T10:32:11-00:00.

Initially I thought this is a thoughtless decision by them all, but then I've learnt that it's a timestamp format recommended by the World Wide Web Consortium, and has its own predefined date constant DATE_W3C. No more questions, period.

Issues In WordPress

Say for example, that in WordPress Dashboard > Settings > General I set the Timezone to New York.

Now, this code <?php get_the_date( 'c' ) ?> in a template (themes or plugins as aforementioned) would output something like this: 2012-06-14T10:32:11-00:00

See the mistake? Yeah, when it SHOULD be this 2012-06-14T10:32:11-04:00 WordPress outputs this 2012-06-14T10:32:11-00:00

This is the case even with the themes and plugins developed by core WordPress developers.

The date and time are absolutely right, wrt to the timezone that is America/New_York. But the timezone offset i.e. the difference to GMT/UTC is NOT. That's not a small problem, it's WRONG time!

The solution

At first I changed all instances of get_the_date( 'c' ); and get_the_modified_date( 'c' ); to get_the_date( 'Y-m-d\TH:i:sP' ); and get_the_modified_date( 'Y-m-d\TH:i:sP' ); respectively, and that seemed to have solved the problem (i.e. showing the right offset).

The real problem was when I realized that I'd have to make these changes to a few plugins that I use (yes, they output timestamps, the Facebook plugin's open graph feature for example). This is not viable. So, I started looking for alternatives.

Thanks to the examples in the PHP Manual functions reference for Date/Time, I realized that I could possibly override WordPress' Timezone setting with something like this in functions.php (right after the first <?php):

date_default_timezone_set('America/New_York');

And voila! get_the_date( 'c' ); and get_the_modified_date( 'c' ); now started showing the right date, time and timezone offset! One change to rule them all!

Other Links


Pre-Edit

Use Y-m-d\TH:i:sP instead of c -- timestamp format remains the same, but it shows the right time zone offset.

This PHP Date() Cheatsheat was very helpful.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.