I've got a WordPress cron job that sends an email periodically and saves the timestamp when it was sent as an option, and I'd like to display a date on a settings page. Something like, "The last email was sent on 'x'". I'm on the west coast of the US, so our time is currently seven hours off of UTC.

My expected output from date_i18n(), passing it the timestamp, would be a locally formatted date with a seven hour adjustment from UTC. However, it returns the time in UTC. Even trying to get the current time doesn't return what I would think would be the expected output.

For example: echo date_i18n('F d, Y H:i'); outputs April 05, 2013 11:36 as expected, but echo date_i18n('F d, Y H:i',time()); outputs April 05, 2013 18:36.

Is this intentional? How can I return a locally formatted date from a preexisting time stamp? Thanks for any help.

  • Have you set your timezone in Settings->General?
    – vancoder
    Apr 5, 2013 at 19:16
  • Yes, to Los Angeles. Apr 5, 2013 at 19:51

7 Answers 7


I know I'm three months late, but the function you want here is WordPress' get_date_from_gmt().

The function accepts a GMT/UTC date in Y-m-d H:i:s format as the first parameter, and your desired date format as the second parameter. It'll convert your date to the local timezone as set on the Settings screen.

Example usage:

echo get_date_from_gmt( date( 'Y-m-d H:i:s', $my_unix_timestamp ), 'F j, Y H:i:s' );

  • 2
    Killer thanks, saw this popup in my notifications just now. I switched it to the correct answer. Jul 22, 2013 at 18:45
  • 1
    I added the date and time configuration: echo get_date_from_gmt ( date( 'Y-m-d H:i:s', $my_timestamp ), get_option('date_format') . ' - '. get_option('time_format') ); Jul 21, 2014 at 23:31
  • @NabilKadimi that's a great addition, but it still doesn't translate the string to the correct language. See my answer for a function that takes into account all three of the configured language, timezone, and date format.
    – Flimm
    May 30, 2019 at 18:13

From the codex:

current_time('timestamp') should be used in lieu of time() to return the blog's local time. In WordPress, PHP's time() will always return UTC and is the same as calling current_time('timestamp', true).

Try this:

define( 'MY_TIMEZONE', (get_option( 'timezone_string' ) ? get_option( 'timezone_string' ) : date_default_timezone_get() ) );
date_default_timezone_set( MY_TIMEZONE );
echo date_i18n('F d, Y H:i', 1365194723);

This sets the default PHP date to WP's timezone_string option, if available, for the duration of the script.

  • 1
    Right, but what if I have an arbitrary timestamp? Say from a couple days ago, how do I get the adjusted time rather than UTC time? Apr 5, 2013 at 19:49
  • does date_i18n('F d, Y H:i', $your_timestamp) not work?
    – vancoder
    Apr 5, 2013 at 20:41
  • Nope, even tried it on a vanilla WP install with 2012 just running this echo date_i18n('F d, Y H:i',1365194723) statement at the top of index.php, that gives me UTC rather than US West Coast time. Apr 5, 2013 at 20:47
  • You're right, it looks like date_i18n is mainly for local formatting of dates, rather than date adjustment. I have updated my answer.
    – vancoder
    Apr 5, 2013 at 21:01
  • 1
    WordPress calls date_default_timezone_set( 'UTC' );, it seems like a bad idea to override this by calling date_default_timezone_set yourself, as WordPress code and plugins may be relying on that behaviour.
    – Flimm
    May 30, 2019 at 16:39

date_i18n($format, $timestamp) formats according to the locale, but not the timezone. get_date_from_gmt($datestring, $format) formats according to the timezone, but not the locale. To get formatting according to both the timezone and the locale, I am doing the following:

function local_date_i18n($format, $timestamp) {
    $timezone_str = get_option('timezone_string') ?: 'UTC';
    $timezone = new \DateTimeZone($timezone_str);

    // The date in the local timezone.
    $date = new \DateTime(null, $timezone);
    $date_str = $date->format('Y-m-d H:i:s');

    // Pretend the local date is UTC to get the timestamp
    // to pass to date_i18n().
    $utc_timezone = new \DateTimeZone('UTC');
    $utc_date = new \DateTime($date_str, $utc_timezone);
    $timestamp = $utc_date->getTimestamp();

    return date_i18n($format, $timestamp, true);

Example program:

$format = 'F d, Y H:i';
$timestamp = 1365186960;
$local = local_date_i18n($format, $timestamp);
$gmt = date_i18n($format, $timestamp);
echo "Local: ", $local, " UTC: ", $gmt;

Output for the timezone of Los Angeles:

Local: April 05, 2013 11:36 UTC: April 05, 2013 18:36



Converting UTC to string in timezone, language and format in WordPress' options

I've created a well-document function that converts a date-time string in UTC to a pretty date-time string in the correct language, format and timezone. Feel free to copy it.

For example, passing in "2019-05-30 18:06:01" (in UTC) would return "Maggio 30, 2019 10:06 am".

 * Given a string with the date and time in UTC, returns a pretty string in the
 * configured language, format and timezone in WordPress' options.
 * @param string $utc_date_and_time 
 *      e.g: "2019-05-30 18:06:01"
 *      This argument must be in UTC.
 * @return string 
 *      e.g: "Maggio 30, 2019 10:06 am"
 *      This returns a pretty datetime string in the correct language and
 *      following the admin's settings.
function pretty_utc_date( string $utc_date ): string {
    if (! preg_match( '/^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$/', $utc_date ) ) {
        /* I have not tested other formats, so only this one allowed. */
        throw new InvalidArgumentException( "Expected argument to be in YYYY-MM-DD hh:mm:ss format" );

    $date_in_local_timezone = get_date_from_gmt( $utc_date );

    /* $date_in_local_timezone is now something like "2019-05-30 10:06:01"
     * in the timezone of get_option( 'timezone_string' ), configured in
     * WordPress' general settings in the backend user interface.

    /* Unfortunately, we can't just pass this to WordPress' date_i18n, as that
     * expects the second argument to be the number of seconds since 1/Jan/1970
     * 00:00:00 in the timezone of get_option( 'timezone_string' ), which is not the
     * same as a UNIX epoch timestamp, which is the number of seconds since
     * 1/Jan/1970 00:00:00 GMT. */
    $seconds_since_local_1_jan_1970 =
        (new DateTime( $date_in_local_timezone, new DateTimeZone( 'UTC' ) ))
    // e.g: 1559210761

    /* Administrators can set a preferred date format and a preferred time
     * format in WordPress' general settings in the backend user interface, we
     * need to retrieve that. */
    $settings_format = get_option( 'date_format' ) . ' '. get_option( 'time_format' );
    // $settings_format is in this example "F j, Y g:i a"

    /* In this example, the installation of WordPress has been set to Italian,
     * and the final result is "Maggio 30, 2019 10:06 am" */
    return date_i18n( $settings_format, $seconds_since_local_1_jan_1970 );




Add timezone offset to your timestamp.

$offset = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
return date_i18n( get_option( 'date_format' ), $ts + $offset );

or better;

$tz = new DateTimeZone( get_option( 'timezone_string' ) );
$offset_for_that_time = timezone_offset_get ( $tz , new DateTime("@{$ts}") );
return date_i18n ( get_option( 'date_format' ), $ts + offset_for_that_time );

This is what seems to work on my machine (none of the other stuff worked):

$tz = new DateTimeZone(get_option('timezone_string'));
$dtz = new DateTimeZone('GMT');
foreach($posts as $key => $post){
    $gmt_date = DateTime::createFromFormat('Y-m-d H:i:s', $post->PostDateGMT, $dtz);
    $posts[$key]->PostDateGMT = $gmt_date->format('Y-m-d H:i:s');

Original code: https://www.simonholywell.com/post/2013/12/convert-utc-to-local-time/

It's not using date_l18n() but I guess one could use it later-on...

  • get_the_time has accepted a $post argument since around 2008.
    – Walf
    Jun 30, 2022 at 8:05

Timestamps do not have a timezone, so you almost never need to operate on them, mathematically.

Since WordPress v5.3, the easiest solution for specific timestamps is wp_date():

$format = get_option( 'time_format' ) . ', ' . get_option( 'date_format' );
echo wp_date( $format, $your_timestamp );

For the current date & time, use the aptly named current_datetime:

echo current_datetime()->format( $format );
  • Timestamps are the number of seconds since 1 January 1970 00:00 UTC for some definitions of a timestamp, or the number of seconds since 1 January 1970 in the local time zone for some definitions of a timestamp.
    – Flimm
    Jun 30, 2022 at 10:14
  • @Flimm In PHP (and thus WordPress), timestamps are always in GMT. See time().
    – Walf
    Jul 1, 2022 at 4:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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