GuessFromMsTzId.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. declare(strict_types=1);
  3. namespace Sabre\VObject\TimezoneGuesser;
  4. use DateTimeZone;
  5. use Sabre\VObject\Component\VTimeZone;
  6. class GuessFromMsTzId implements TimezoneGuesser
  7. {
  8. /**
  9. * List of microsoft exchange timezone ids.
  10. *
  11. * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx
  12. */
  13. public static $microsoftExchangeMap = [
  14. 0 => 'UTC',
  15. 31 => 'Africa/Casablanca',
  16. // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo.
  17. // I'm not even kidding.. We handle this special case in the
  18. // getTimeZone method.
  19. 2 => 'Europe/Lisbon',
  20. 1 => 'Europe/London',
  21. 4 => 'Europe/Berlin',
  22. 6 => 'Europe/Prague',
  23. 3 => 'Europe/Paris',
  24. 69 => 'Africa/Luanda', // This was a best guess
  25. 7 => 'Europe/Athens',
  26. 5 => 'Europe/Bucharest',
  27. 49 => 'Africa/Cairo',
  28. 50 => 'Africa/Harare',
  29. 59 => 'Europe/Helsinki',
  30. 27 => 'Asia/Jerusalem',
  31. 26 => 'Asia/Baghdad',
  32. 74 => 'Asia/Kuwait',
  33. 51 => 'Europe/Moscow',
  34. 56 => 'Africa/Nairobi',
  35. 25 => 'Asia/Tehran',
  36. 24 => 'Asia/Muscat', // Best guess
  37. 54 => 'Asia/Baku',
  38. 48 => 'Asia/Kabul',
  39. 58 => 'Asia/Yekaterinburg',
  40. 47 => 'Asia/Karachi',
  41. 23 => 'Asia/Calcutta',
  42. 62 => 'Asia/Kathmandu',
  43. 46 => 'Asia/Almaty',
  44. 71 => 'Asia/Dhaka',
  45. 66 => 'Asia/Colombo',
  46. 61 => 'Asia/Rangoon',
  47. 22 => 'Asia/Bangkok',
  48. 64 => 'Asia/Krasnoyarsk',
  49. 45 => 'Asia/Shanghai',
  50. 63 => 'Asia/Irkutsk',
  51. 21 => 'Asia/Singapore',
  52. 73 => 'Australia/Perth',
  53. 75 => 'Asia/Taipei',
  54. 20 => 'Asia/Tokyo',
  55. 72 => 'Asia/Seoul',
  56. 70 => 'Asia/Yakutsk',
  57. 19 => 'Australia/Adelaide',
  58. 44 => 'Australia/Darwin',
  59. 18 => 'Australia/Brisbane',
  60. 76 => 'Australia/Sydney',
  61. 43 => 'Pacific/Guam',
  62. 42 => 'Australia/Hobart',
  63. 68 => 'Asia/Vladivostok',
  64. 41 => 'Asia/Magadan',
  65. 17 => 'Pacific/Auckland',
  66. 40 => 'Pacific/Fiji',
  67. 67 => 'Pacific/Tongatapu',
  68. 29 => 'Atlantic/Azores',
  69. 53 => 'Atlantic/Cape_Verde',
  70. 30 => 'America/Noronha',
  71. 8 => 'America/Sao_Paulo', // Best guess
  72. 32 => 'America/Argentina/Buenos_Aires',
  73. 60 => 'America/Godthab',
  74. 28 => 'America/St_Johns',
  75. 9 => 'America/Halifax',
  76. 33 => 'America/Caracas',
  77. 65 => 'America/Santiago',
  78. 35 => 'America/Bogota',
  79. 10 => 'America/New_York',
  80. 34 => 'America/Indiana/Indianapolis',
  81. 55 => 'America/Guatemala',
  82. 11 => 'America/Chicago',
  83. 37 => 'America/Mexico_City',
  84. 36 => 'America/Edmonton',
  85. 38 => 'America/Phoenix',
  86. 12 => 'America/Denver', // Best guess
  87. 13 => 'America/Los_Angeles', // Best guess
  88. 14 => 'America/Anchorage',
  89. 15 => 'Pacific/Honolulu',
  90. 16 => 'Pacific/Midway',
  91. 39 => 'Pacific/Kwajalein',
  92. ];
  93. public function guess(VTimeZone $vtimezone, bool $throwIfUnsure = false): ?DateTimeZone
  94. {
  95. // Microsoft may add a magic number, which we also have an
  96. // answer for.
  97. if (!isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) {
  98. return null;
  99. }
  100. $cdoId = (int) $vtimezone->{'X-MICROSOFT-CDO-TZID'}->getValue();
  101. // 2 can mean both Europe/Lisbon and Europe/Sarajevo.
  102. if (2 === $cdoId && false !== strpos((string) $vtimezone->TZID, 'Sarajevo')) {
  103. return new DateTimeZone('Europe/Sarajevo');
  104. }
  105. if (isset(self::$microsoftExchangeMap[$cdoId])) {
  106. return new DateTimeZone(self::$microsoftExchangeMap[$cdoId]);
  107. }
  108. return null;
  109. }
  110. }