50

Can someone tell me how to get the time zone that is set in the WordPress Admin?

For example, if the blog is set to Eastern time, I need this exact string to print out:

US/Eastern

This is for a function that lives in functions.php in my theme.

79

if you need the gmt_offset then

<?php echo get_option('gmt_offset'); ?>

this will give you an integer like 2 or -2.

and if you need the timezone string use

<?php echo get_option('timezone_string'); ?>

this will give you a string like America/Indianapolis

  • 6
    My timezone_string is in the database but it is empty, even after selecting a different timezone on the settings page. What might be the case? (WP3.6) – user2019515 Sep 13 '13 at 22:48
  • Does gmt_offest take daylight savings into account based on the site's timezone setting? – squarecandy Dec 19 '13 at 4:04
  • 6
    @user2019515 If you choose a city as a timezone it will save to the "timezone_string" option but if you choose a Manual Offset (UTC+1 for instance) it is saved to the "gmt_offset" option (as "1") and timezone_string remains empty. – Berend Mar 27 '17 at 18:06
15

The unfortunate situation is that there are indeed two different options:

  1. Newer timezone_string, which saves PHP–style time zone.
  2. Older gmt_offset, which saves numeric float offset in hours.

But in newer environments timezone_string actually overrides gmt_offset, the value returned by the latter will be based on the former. However the opposite isn't true — gmt_offset might be valid, while timezone_string is empty.

WordPress 5.3 had shipped wp_timezone() function, that abstracts this and returns a valid DateTimeZone object, regardless of underlying WP settings.

Before that I had a take on it implemented in my WpDateTime library (for trivia that was used as a basis for core implementation):

class WpDateTimeZone extends \DateTimeZone {
    /**
     * Determine time zone from WordPress options and return as object.
     *
     * @return static
     */
    public static function getWpTimezone() {
        $timezone_string = get_option( 'timezone_string' );
        if ( ! empty( $timezone_string ) ) {
            return new static( $timezone_string );
        }
        $offset  = get_option( 'gmt_offset' );
        $hours   = (int) $offset;
        $minutes = abs( ( $offset - (int) $offset ) * 60 );
        $offset  = sprintf( '%+03d:%02d', $hours, $minutes );
        return new static( $offset );
    }
}
  • 1
    This should be the accepted answer. People will run into bugs if they rely solely on get_option('timezone_string'). – DiscoInfiltrator Aug 14 '18 at 20:25
  • This is the correct answer. – Lucas Bustamante Dec 9 '18 at 15:41
  • Isnt use of (int) for $hours and floor for $minutes problematic? According to documentation, (int) and floor are almost the same except (int) will round -4.5 to -4 and floor will round it to -5. This seems like it will give incorrect negative timezone offsets? – Mikepote May 13 at 13:22
  • 1
    @Mikepote yeah, this was fixed in the lib a long time ago, just stale copy of the code in the answer here. – Rarst May 15 at 10:54
  • Oh my god why did they implement it like this .... It costed me a full hour tilt – Blackbam Jun 21 at 15:29
9

Check the Option Reference page. The option gmt_offset returns an integer. For example, if the timezone is set to Eastern time (e.g. America/New_York), gmt_offset should be -5.

2

Don't think you're gonna get a string like US/Eastern without storing all the strings you want in an array and referring to them. Using PHP you can get the timezone abbreviation, ie EST; and if you have those values stored in an array with the strings you want, you can look them up.

<?php date_default_timezone_set(get_option('timezone_string'));

      echo date('T'); // will give you three-character string like "EST"

      $timezones = array (
          'EST' => 'US/Eastern',
          'CST' => 'US/Central',
          // etc, etc, etc.
          );

      echo $timezones [ date('T') ]; // should be what you want.
 ?>
1

To add to Bainternet (I am adding this as an answer because I cannot comment -- I have less than 50 points on WP Development stack).

WordPress will only store a timezone string if you select a timezone string in the general settings. UTF selection is where it defaults in the list, but you can scroll way up to timezone strings. If you set a timezone string, both the UTF and the Timezone string will be set. They will be the same (meaning, the UTF gets reset to the new zone when you select a timezone string timezone).

(WordPress 4)

0

There are a few options, none of which really work great. This is a WordPress bug, and it genuinely sucks because the time is wrong unless you set your site to UTC... which is confusing and not always even possible.

This next code I think only works if you choose your Timezone (Under Settings -> General in admin) as a named city instead of by an GMT number offset. I haven't tested this but it's very possible that get_option('gmt_offset') is set when get_option('timezone_string') is not.

date_default_timezone_set(get_option('timezone_string'));

The downside of this is that WordPress assumes PHP is set to UTC when making mysql timestamps, so you can mess up your database a little bit whenever you switch timezones! Not to mention other WP plugins may assume that the PHP environment is always in UTC.

So, if you just want a correct time -- you can force your timestamp to be in UTC with:

get_post_time('c', true); //should work for non-post objects.

Unfortunately, although correct, it'll make the timezone get set to UTC.

And note that you can't both use the "true" flag and the default timezone_set function.

Any proper solution is gonna be a code-snippet that accounts for both gmt_offset AND timezone_string and uses them to set a timezone on some input. WP assumes that PHP set to UTC when doing mysql timestamps, and it might break other plugins.

There's one such solution on https://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/ but, again this is a BUG, so you should use the get_post_time($date_format, TRUE) code to get a timestamp that is actually correct.

0

Given the fact that wordpress keeps the timezone string in the options table, you can use the object oriented way of getting the right time on your wordpress site:

$tz = new DateTimeZone(get_option('timezone_string'));
$dt = new DateTime("now", $tz);

$page .= "<p> DateTime " . $dt->format("Y-m-d H:i:s") . "</p>";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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