FindFromTimezoneMap.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. declare(strict_types=1);
  3. namespace Sabre\VObject\TimezoneGuesser;
  4. use DateTimeZone;
  5. /**
  6. * Some clients add 'X-LIC-LOCATION' with the olson name.
  7. */
  8. class FindFromTimezoneMap implements TimezoneFinder
  9. {
  10. private $map = [];
  11. private $patterns = [
  12. '/^\((UTC|GMT)(\+|\-)[\d]{2}\:[\d]{2}\) (.*)/',
  13. '/^\((UTC|GMT)(\+|\-)[\d]{2}\.[\d]{2}\) (.*)/',
  14. ];
  15. public function find(string $tzid, bool $failIfUncertain = false): ?DateTimeZone
  16. {
  17. // Next, we check if the tzid is somewhere in our tzid map.
  18. if ($this->hasTzInMap($tzid)) {
  19. return new DateTimeZone($this->getTzFromMap($tzid));
  20. }
  21. // Some Microsoft products prefix the offset first, so let's strip that off
  22. // and see if it is our tzid map. We don't want to check for this first just
  23. // in case there are overrides in our tzid map.
  24. foreach ($this->patterns as $pattern) {
  25. if (!preg_match($pattern, $tzid, $matches)) {
  26. continue;
  27. }
  28. $tzidAlternate = $matches[3];
  29. if ($this->hasTzInMap($tzidAlternate)) {
  30. return new DateTimeZone($this->getTzFromMap($tzidAlternate));
  31. }
  32. }
  33. return null;
  34. }
  35. /**
  36. * This method returns an array of timezone identifiers, that are supported
  37. * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers().
  38. *
  39. * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because:
  40. * - It's not supported by some PHP versions as well as HHVM.
  41. * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions.
  42. * (See timezonedata/php-bc.php and timezonedata php-workaround.php)
  43. *
  44. * @return array
  45. */
  46. private function getTzMaps()
  47. {
  48. if ([] === $this->map) {
  49. $this->map = array_merge(
  50. include __DIR__.'/../timezonedata/windowszones.php',
  51. include __DIR__.'/../timezonedata/lotuszones.php',
  52. include __DIR__.'/../timezonedata/exchangezones.php',
  53. include __DIR__.'/../timezonedata/php-workaround.php'
  54. );
  55. }
  56. return $this->map;
  57. }
  58. private function getTzFromMap(string $tzid): string
  59. {
  60. return $this->getTzMaps()[$tzid];
  61. }
  62. private function hasTzInMap(string $tzid): bool
  63. {
  64. return isset($this->getTzMaps()[$tzid]);
  65. }
  66. }