How to convert a GMT/UTC timestamp to local time in WordPress

WordPress goes to great lengths in order to provide us with a localized environment, displaying dates and times in the correct format and even language. However, since it uses its own timezone setting, some native PHP functions are no longer applicable (or don’t return correct results), such as the date() function which returns a date/time string depending on the timezone configuration of PHP itself, ignoring the WordPress setting.

Recently, I retrieved from a third-party API a timestamp, which I needed to convert to a WordPress-correct timestamp. WordPress already provides a great function, date_i18n() (i18n stands for internationalization, as there are 18 letters between the beginning i and the ending n), which seemingly supports GMT/UTC timestamps, but once I tried it I quickly realized its $gmt parameter only applies if you don’t provide your own timestamp.

There is however, a little known function called get_gmt_from_date() which almost does what I needed, but not quite. The problem is that it won’t accept a timestamp, but a string in the format Y-m-d H:i:s (e.g. 2018-03-19 23:59:59). No problem! Let’s create our own little function that will wrap get_gmt_from_date() returning exactly what we need.

function my_gmt_to_local_timestamp( $gmt_timestamp ) {
	$iso_date        = date( 'Y-m-d H:i:s', $gmt_timestamp );
	$local_timestamp = get_date_from_gmt( $iso_date, 'U' );

	return $local_timestamp;
}

First, we convert our GMT timestamp to the format required. get_date_from_gmt() supports a seconds parameter, which is the format with which to return the result. We can pass “U” as the return format which, according to the documentation is the timestamp. What we get, is the localized timestamp, suitable to be used with all WordPress-provided date/time functions.

We can simplify our function to a one-liner by eliminating the variables:

function my_gmt_to_local_timestamp( $gmt_timestamp ) {
	return get_date_from_gmt( date( 'Y-m-d H:i:s', $gmt_timestamp ), 'U' );
}

That’s it! You can now use the local timestamp with date_i18n() or any other WordPress date/time function you want. You can even skip creating the whole function and just type its one line of code every time you need it; it’s not that complicated. But I do tend to forget, so a well named function always helps :)

PHP timestamps vs WordPress timestamps

Note that timestamps used by WordPress are generated by WordPress-provided current_time() and are usually localized.

In contrast, PHP’s functions date(), gmdate() and others, always handle the timestamp format “U” as GMT/UTC. This can be observed by running:

$tz = date_default_timezone_get();
date_default_timezone_set( 'Europe/Athens' );

// E.g. output: 1521481898 2018-03-19 19:51:38 Europe/Athens
var_dump( date( 'U Y-m-d H:i:s e') );
// E.g. output: 1521481898 2018-03-19 17:51:38 UTC
var_dump( gmdate( 'U Y-m-d H:i:s e') );

date_default_timezone_set( $tz );

Notice how the timestamps (the first number in each line) are the same, but the actual date/time is different. Always check the source and correctness of your timestamps when working with WordPress.

Troubleshooting

If the function returns the same timestamp as the one you provided, make sure you have actually selected a correct timezone from Settings → General → Timezone. Note that the timestamp returned may still be the same as the GMT/UTC timestamp you passed, if the timezone selected is UTC, UTC+0, or a location that is close to UTC time and observes DST at some point. (e.g. Europe/London in winter and Atlantic/Azores in the summer).

Related Articles

4 comments

  1. FBtheNobie says:

    Thank you for the explanation Anastis.
    What if I have an specific date on display like 19:00 and I want it to show in visitor’s time zone? What’s the best way to do it?
    Thank you verymuch!

    1. Anastis Sourgoutsidis says:

      This is better achieved via JavaScript, as the visitor’s browser already knows the correct timezone, and you avoid the need for cookies and round-trips.
      You can use or get inspiration from plugins that do just that:
      Localize Time
      Local Time

  2. Radley Sustaire says:

    Using the “U” option with get_date_from_gmt does not just give you a timestamp, it gives you the seconds from unix epoch which is based in GMT. So you are losing the timezone offset you wanted to get. Try strtotime instead of “U”, this worked for me:

    get_date_from_gmt( $start_date, ‘U’ ); // Returns a timestamp in UTC+0 timezone

    strtotime( get_date_from_gmt( $start_date ) ); // Returns local time WP time

    1. Anastis Sourgoutsidis says:

      Hey Radley!
      Thanks for clearing things up for our readers!

      Some comments however:

      1. it gives you the seconds from unix epoch: this is the definition of the Unix timestamp :D
      2. which is based in GMT. So you are losing the timezone offset you wanted to get: This is exactly why this article exists! Even from the title, I assume you have a GMT/UTC timestamp (e.g. coming from an API) that you need to convert to local WordPress time. There is no timezone to lose.

Leave a Reply

Your email address will not be published. Required fields are marked *