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;
 | 
						|
	}
 | 
						|
}
 |