Timezones.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Intl;
  11. use Symfony\Component\Intl\Exception\MissingResourceException;
  12. use Symfony\Component\Intl\Exception\RuntimeException;
  13. /**
  14. * Gives access to timezone-related ICU data.
  15. *
  16. * @author Roland Franssen <franssen.roland@gmail.com>
  17. */
  18. final class Timezones extends ResourceBundle
  19. {
  20. /**
  21. * @return string[]
  22. */
  23. public static function getIds(): array
  24. {
  25. return self::readEntry(['Zones'], 'meta');
  26. }
  27. public static function exists(string $timezone): bool
  28. {
  29. try {
  30. self::readEntry(['Names', $timezone]);
  31. return true;
  32. } catch (MissingResourceException $e) {
  33. try {
  34. new \DateTimeZone($timezone);
  35. return true;
  36. } catch (\Exception $e) {
  37. return false;
  38. }
  39. }
  40. }
  41. /**
  42. * @throws MissingResourceException if the timezone identifier does not exist or is an alias
  43. */
  44. public static function getName(string $timezone, string $displayLocale = null): string
  45. {
  46. return self::readEntry(['Names', $timezone], $displayLocale);
  47. }
  48. /**
  49. * @return string[]
  50. */
  51. public static function getNames(string $displayLocale = null): array
  52. {
  53. return self::asort(self::readEntry(['Names'], $displayLocale), $displayLocale);
  54. }
  55. /**
  56. * @throws \Exception if the timezone identifier does not exist
  57. * @throws RuntimeException if there's no timezone DST transition information available
  58. */
  59. public static function getRawOffset(string $timezone, int $timestamp = null): int
  60. {
  61. if (null === $timestamp) {
  62. $timestamp = time();
  63. }
  64. $transitions = (new \DateTimeZone($timezone))->getTransitions($timestamp, $timestamp);
  65. if (!isset($transitions[0]['offset'])) {
  66. throw new RuntimeException('No timezone transitions available.');
  67. }
  68. return $transitions[0]['offset'];
  69. }
  70. public static function getGmtOffset(string $timezone, int $timestamp = null, string $displayLocale = null): string
  71. {
  72. $offset = self::getRawOffset($timezone, $timestamp);
  73. $abs = abs($offset);
  74. return sprintf(self::readEntry(['Meta', 'GmtFormat'], $displayLocale), sprintf(self::readEntry(['Meta', 'HourFormat'.(0 <= $offset ? 'Pos' : 'Neg')], $displayLocale), $abs / 3600, $abs / 60 % 60));
  75. }
  76. /**
  77. * @throws MissingResourceException if the timezone identifier has no associated country code
  78. */
  79. public static function getCountryCode(string $timezone): string
  80. {
  81. return self::readEntry(['ZoneToCountry', $timezone], 'meta');
  82. }
  83. /**
  84. * @throws MissingResourceException if the country code does not exist
  85. */
  86. public static function forCountryCode(string $country): array
  87. {
  88. try {
  89. return self::readEntry(['CountryToZone', $country], 'meta');
  90. } catch (MissingResourceException $e) {
  91. if (Countries::exists($country)) {
  92. return [];
  93. }
  94. if (Countries::exists(strtoupper($country))) {
  95. throw new MissingResourceException(sprintf('Country codes must be in uppercase, but "%s" was passed. Try with "%s" country code instead.', $country, strtoupper($country)));
  96. }
  97. throw $e;
  98. }
  99. }
  100. protected static function getPath(): string
  101. {
  102. return Intl::getDataDirectory().'/'.Intl::TIMEZONE_DIR;
  103. }
  104. }