class-sitemap-timezone.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 to be converted to a DateTime object.
  36. *
  37. * @return DateTime|null in site's time zone
  38. */
  39. public function get_datetime_with_timezone( $datetime_string ) {
  40. static $utc_timezone, $local_timezone;
  41. if ( ! isset( $utc_timezone ) ) {
  42. $utc_timezone = new DateTimeZone( 'UTC' );
  43. $local_timezone = new DateTimeZone( $this->get_timezone_string() );
  44. }
  45. if ( ! empty( $datetime_string ) && WPSEO_Utils::is_valid_datetime( $datetime_string ) ) {
  46. $datetime = new DateTime( $datetime_string, $utc_timezone );
  47. $datetime->setTimezone( $local_timezone );
  48. return $datetime;
  49. }
  50. return null;
  51. }
  52. /**
  53. * Returns the timezone string for a site, even if it's set to a UTC offset
  54. *
  55. * Adapted from http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155
  56. *
  57. * @return string valid PHP timezone string
  58. */
  59. private function determine_timezone_string() {
  60. // If site timezone string exists, return it.
  61. $timezone = get_option( 'timezone_string' );
  62. if ( ! empty( $timezone ) ) {
  63. return $timezone;
  64. }
  65. // Get UTC offset, if it isn't set then return UTC.
  66. $utc_offset = (int) get_option( 'gmt_offset', 0 );
  67. if ( 0 === $utc_offset ) {
  68. return 'UTC';
  69. }
  70. // Adjust UTC offset from hours to seconds.
  71. $utc_offset *= HOUR_IN_SECONDS;
  72. // Attempt to guess the timezone string from the UTC offset.
  73. $timezone = timezone_name_from_abbr( '', $utc_offset );
  74. if ( false !== $timezone ) {
  75. return $timezone;
  76. }
  77. // Last try, guess timezone string manually.
  78. $timezone_list = timezone_abbreviations_list();
  79. foreach ( $timezone_list as $abbr ) {
  80. foreach ( $abbr as $city ) {
  81. if ( $city['offset'] === $utc_offset ) {
  82. return $city['timezone_id'];
  83. }
  84. }
  85. }
  86. // Fallback to UTC.
  87. return 'UTC';
  88. }
  89. /**
  90. * Returns the correct timezone string
  91. *
  92. * @return string
  93. */
  94. private function get_timezone_string() {
  95. if ( '' === $this->timezone_string ) {
  96. $this->timezone_string = $this->determine_timezone_string();
  97. }
  98. return $this->timezone_string;
  99. }
  100. }