class-sitemap-timezone.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\XML_Sitemaps
  6. */
  7. /**
  8. * Class WPSEO_Sitemap_Timezone.
  9. */
  10. class WPSEO_Sitemap_Timezone {
  11. /**
  12. * Holds the timezone string value to reuse for performance.
  13. *
  14. * @var string $timezone_string
  15. */
  16. private $timezone_string = '';
  17. /**
  18. * Format arbitrary UTC datetime string to desired form in site's time zone.
  19. *
  20. * @param string $datetime_string The input datetime string in UTC time zone.
  21. * @param string $format Date format to use.
  22. *
  23. * @return string
  24. */
  25. public function format_date( $datetime_string, $format = 'c' ) {
  26. $date_time = $this->get_datetime_with_timezone( $datetime_string );
  27. if ( is_null( $date_time ) ) {
  28. return '';
  29. }
  30. return $date_time->format( $format );
  31. }
  32. /**
  33. * Get the datetime object, in site's time zone, if the datetime string was valid
  34. *
  35. * @param string $datetime_string The datetime string in UTC time zone, that needs
  36. * to be converted to a DateTime object.
  37. *
  38. * @return DateTime|null DateTime object in site's time zone.
  39. */
  40. public function get_datetime_with_timezone( $datetime_string ) {
  41. static $utc_timezone, $local_timezone;
  42. if ( ! isset( $utc_timezone ) ) {
  43. $utc_timezone = new DateTimeZone( 'UTC' );
  44. $local_timezone = new DateTimeZone( $this->get_timezone_string() );
  45. }
  46. if ( ! empty( $datetime_string ) && WPSEO_Utils::is_valid_datetime( $datetime_string ) ) {
  47. $datetime = new DateTime( $datetime_string, $utc_timezone );
  48. $datetime->setTimezone( $local_timezone );
  49. return $datetime;
  50. }
  51. return null;
  52. }
  53. /**
  54. * Returns the timezone string for a site, even if it's set to a UTC offset.
  55. *
  56. * Adapted from {@link http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155}.
  57. *
  58. * @return string Valid PHP timezone string.
  59. */
  60. private function determine_timezone_string() {
  61. // If site timezone string exists, return it.
  62. $timezone = get_option( 'timezone_string' );
  63. if ( ! empty( $timezone ) ) {
  64. return $timezone;
  65. }
  66. // Get UTC offset, if it isn't set then return UTC.
  67. $utc_offset = (int) get_option( 'gmt_offset', 0 );
  68. if ( 0 === $utc_offset ) {
  69. return 'UTC';
  70. }
  71. // Adjust UTC offset from hours to seconds.
  72. $utc_offset *= HOUR_IN_SECONDS;
  73. // Attempt to guess the timezone string from the UTC offset.
  74. $timezone = timezone_name_from_abbr( '', $utc_offset );
  75. if ( false !== $timezone ) {
  76. return $timezone;
  77. }
  78. // Last try, guess timezone string manually.
  79. $timezone_list = timezone_abbreviations_list();
  80. foreach ( $timezone_list as $abbr ) {
  81. foreach ( $abbr as $city ) {
  82. if ( $city['offset'] === $utc_offset ) {
  83. return $city['timezone_id'];
  84. }
  85. }
  86. }
  87. // Fallback to UTC.
  88. return 'UTC';
  89. }
  90. /**
  91. * Returns the correct timezone string.
  92. *
  93. * @return string
  94. */
  95. private function get_timezone_string() {
  96. if ( '' === $this->timezone_string ) {
  97. $this->timezone_string = $this->determine_timezone_string();
  98. }
  99. return $this->timezone_string;
  100. }
  101. }