5

I need to use PHP's DateTime(). It's currently displaying GMT time instead of the time that's set for the timezone setting (EST) in the WordPress Admin.

How can this be converted to show the the time base

$time = new DateTime();
echo $time->format("Y-m-d h:i:s");

// 2015-08-12 04:35:34 (gmt)
// 2015-08-12 12:35:34 (what i want -- EST)
8

I'm not sure why EliasNS' answer is marked correct, as far as I'm aware (and from the documentation), the second parameter of DateTime::__construct(), if provided, should be a DateTimeZone instance.

The problem then becomes, how we do we create a DateTimeZone instance. This is easy if the user has selected a city as their timezone, but we can work around it if they have set an offset by using the (deprecated) Etc/GMT timezones.

/**
 *  Returns the blog timezone
 *
 * Gets timezone settings from the db. If a timezone identifier is used just turns
 * it into a DateTimeZone. If an offset is used, it tries to find a suitable timezone.
 * If all else fails it uses UTC.
 *
 * @return DateTimeZone The blog timezone
 */
function wpse198435_get_blog_timezone() {

    $tzstring = get_option( 'timezone_string' );
    $offset   = get_option( 'gmt_offset' );

    //Manual offset...
    //@see http://us.php.net/manual/en/timezones.others.php
    //@see https://bugs.php.net/bug.php?id=45543
    //@see https://bugs.php.net/bug.php?id=45528
    //IANA timezone database that provides PHP's timezone support uses POSIX (i.e. reversed) style signs
    if( empty( $tzstring ) && 0 != $offset && floor( $offset ) == $offset ){
        $offset_st = $offset > 0 ? "-$offset" : '+'.absint( $offset );
        $tzstring  = 'Etc/GMT'.$offset_st;
    }

    //Issue with the timezone selected, set to 'UTC'
    if( empty( $tzstring ) ){
        $tzstring = 'UTC';
    }

    $timezone = new DateTimeZone( $tzstring );
    return $timezone; 
}

Then you can use it as follows:

$time = new DateTime( null, wpse198435_get_blog_timezone() );
  • 1
    This will not correctly handle half-hour timezones, Etc/* are recommended to not be used in general. – Rarst May 4 '17 at 9:39
  • Yes - hence 'deprecated' :). I'm not aware of a better way of handling half-hour off-set timezones. Seems the best solution is to encourage adoption of a city as timezone identifier or avoid DateTimeZone in a WordPress context. – Stephen Harris May 4 '17 at 9:49
  • 2
    I added the answer with my take from my WpDateTime lib. :) – Rarst May 4 '17 at 9:54
3

I had developed a method in my lib to retrieve current WP’s time zone as proper object: WpDateTimeZone::getWpTimezone().

While timezone_string is straightforward (it is already a valid time zone name), gmt_offset case is nasty. Best I could come up with is converting it into a +00:00 format:

$offset  = get_option( 'gmt_offset' );
$hours   = (int) $offset;
$minutes = ( $offset - floor( $offset ) ) * 60;
$offset  = sprintf( '%+03d:%02d', $hours, $minutes )
  • 1
    Requires PHP 5.5 (* ducks *). As @rarst pointed out in his comment on my answer using Etc/* is not recommended, going forward this is the way forward to handle offsets. – Stephen Harris May 4 '17 at 12:42
  • 1
    Requires PHP 5.5 — you say it like it’s a problem... :) – Rarst May 4 '17 at 14:11
-1

DateTime aceppts a DateTimeZone parameter, that you can get from WordPress options. Something like:

$time = new DateTime(NULL, get_option('gmt_offset'));

Hope this helps.

Edit: I'm testing it and I get an error. I don't know how to convert the timezone string to a DateTimeZone object, but that is the way.

  • 1
    Both options return a string. Now we need to create an DateTimeZone object from it. I can't help more :( – EliasNS Aug 12 '15 at 17:14

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.