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"> — </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?
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 PHPDATE_*
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:
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 forDateTime
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:If you are after the PHP DateTimeZone object of your blog’s timezone, see this gist: https://gist.github.com/2724520
(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 this2012-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 this2012-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' );
andget_the_modified_date( 'c' );
toget_the_date( 'Y-m-dTH:i:sP' );
andget_the_modified_date( 'Y-m-dTH: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
):And voila!
get_the_date( 'c' );
andget_the_modified_date( 'c' );
now started showing the right date, time and timezone offset! One change to rule them all!Other Links
List of Supported Timezones in PHP
WordPress Codex: Formatting Date and Time
Pre-Edit
Use
Y-m-dTH:i:sP
instead ofc
— timestamp format remains the same, but it shows the right time zone offset.This PHP Date() Cheatsheat was very helpful.