153 lines
4.3 KiB
PHP
153 lines
4.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Class ActionScheduler_TimezoneHelper
|
|
*/
|
|
abstract class ActionScheduler_TimezoneHelper {
|
|
private static $local_timezone = NULL;
|
|
|
|
/**
|
|
* Set a DateTime's timezone to the WordPress site's timezone, or a UTC offset
|
|
* if no timezone string is available.
|
|
*
|
|
* @since 2.1.0
|
|
*
|
|
* @param DateTime $date
|
|
* @return ActionScheduler_DateTime
|
|
*/
|
|
public static function set_local_timezone( DateTime $date ) {
|
|
|
|
// Accept a DateTime for easier backward compatibility, even though we require methods on ActionScheduler_DateTime
|
|
if ( ! is_a( $date, 'ActionScheduler_DateTime' ) ) {
|
|
$date = as_get_datetime_object( $date->format( 'U' ) );
|
|
}
|
|
|
|
if ( get_option( 'timezone_string' ) ) {
|
|
$date->setTimezone( new DateTimeZone( self::get_local_timezone_string() ) );
|
|
} else {
|
|
$date->setUtcOffset( self::get_local_timezone_offset() );
|
|
}
|
|
|
|
return $date;
|
|
}
|
|
|
|
/**
|
|
* Helper to retrieve the timezone string for a site until a WP core method exists
|
|
* (see https://core.trac.wordpress.org/ticket/24730).
|
|
*
|
|
* Adapted from wc_timezone_string() and https://secure.php.net/manual/en/function.timezone-name-from-abbr.php#89155.
|
|
*
|
|
* If no timezone string is set, and its not possible to match the UTC offset set for the site to a timezone
|
|
* string, then an empty string will be returned, and the UTC offset should be used to set a DateTime's
|
|
* timezone.
|
|
*
|
|
* @since 2.1.0
|
|
* @return string PHP timezone string for the site or empty if no timezone string is available.
|
|
*/
|
|
protected static function get_local_timezone_string( $reset = false ) {
|
|
// If site timezone string exists, return it.
|
|
$timezone = get_option( 'timezone_string' );
|
|
if ( $timezone ) {
|
|
return $timezone;
|
|
}
|
|
|
|
// Get UTC offset, if it isn't set then return UTC.
|
|
$utc_offset = intval( get_option( 'gmt_offset', 0 ) );
|
|
if ( 0 === $utc_offset ) {
|
|
return 'UTC';
|
|
}
|
|
|
|
// Adjust UTC offset from hours to seconds.
|
|
$utc_offset *= 3600;
|
|
|
|
// Attempt to guess the timezone string from the UTC offset.
|
|
$timezone = timezone_name_from_abbr( '', $utc_offset );
|
|
if ( $timezone ) {
|
|
return $timezone;
|
|
}
|
|
|
|
// Last try, guess timezone string manually.
|
|
foreach ( timezone_abbreviations_list() as $abbr ) {
|
|
foreach ( $abbr as $city ) {
|
|
if ( (bool) date( 'I' ) === (bool) $city['dst'] && $city['timezone_id'] && intval( $city['offset'] ) === $utc_offset ) {
|
|
return $city['timezone_id'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// No timezone string
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Get timezone offset in seconds.
|
|
*
|
|
* @since 2.1.0
|
|
* @return float
|
|
*/
|
|
protected static function get_local_timezone_offset() {
|
|
$timezone = get_option( 'timezone_string' );
|
|
|
|
if ( $timezone ) {
|
|
$timezone_object = new DateTimeZone( $timezone );
|
|
return $timezone_object->getOffset( new DateTime( 'now' ) );
|
|
} else {
|
|
return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @deprecated 2.1.0
|
|
*/
|
|
public static function get_local_timezone( $reset = FALSE ) {
|
|
_deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' );
|
|
if ( $reset ) {
|
|
self::$local_timezone = NULL;
|
|
}
|
|
if ( !isset(self::$local_timezone) ) {
|
|
$tzstring = get_option('timezone_string');
|
|
|
|
if ( empty($tzstring) ) {
|
|
$gmt_offset = get_option('gmt_offset');
|
|
if ( $gmt_offset == 0 ) {
|
|
$tzstring = 'UTC';
|
|
} else {
|
|
$gmt_offset *= HOUR_IN_SECONDS;
|
|
$tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 );
|
|
|
|
// If there's no timezone string, try again with no DST.
|
|
if ( false === $tzstring ) {
|
|
$tzstring = timezone_name_from_abbr( '', $gmt_offset, 0 );
|
|
}
|
|
|
|
// Try mapping to the first abbreviation we can find.
|
|
if ( false === $tzstring ) {
|
|
$is_dst = date( 'I' );
|
|
foreach ( timezone_abbreviations_list() as $abbr ) {
|
|
foreach ( $abbr as $city ) {
|
|
if ( $city['dst'] == $is_dst && $city['offset'] == $gmt_offset ) {
|
|
// If there's no valid timezone ID, keep looking.
|
|
if ( null === $city['timezone_id'] ) {
|
|
continue;
|
|
}
|
|
|
|
$tzstring = $city['timezone_id'];
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we still have no valid string, then fall back to UTC.
|
|
if ( false === $tzstring ) {
|
|
$tzstring = 'UTC';
|
|
}
|
|
}
|
|
}
|
|
|
|
self::$local_timezone = new DateTimeZone($tzstring);
|
|
}
|
|
return self::$local_timezone;
|
|
}
|
|
}
|