1 <?php
2
3 /*
4 * This file is part of the ICanBoogie package.
5 *
6 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace ICanBoogie;
13
14 /**
15 * Representation of a timezone.
16 *
17 * <pre>
18 * <?php
19 *
20 * use ICanBoogie\TimeZone;
21 *
22 * $zone = new TimeZone('Europe/Paris');
23 *
24 * echo $zone; // "Europe/Paris"
25 * echo $zone->offset; // 3600
26 * echo $zone->location; // FR,48.86667,2.33333
27 * echo $zone->location->latitude; // 48.86667
28 * </pre>
29 *
30 * @property-read TimeZoneLocation $location Location information for the timezone.
31 * @property-read string $name Name of the timezone.
32 * @property-read int $offset Timezone offset from UTC.
33 */
34 class TimeZone extends \DateTimeZone
35 {
36 static private $utc_time;
37 static private $cache;
38
39 /**
40 * Returns a timezone according to the specified source.
41 *
42 * If the source is already an instance of {@link Zone}, it is returned as is.
43 *
44 * Note: Instances created by the method are shared. That is, equivalent sources yield
45 * the same instance.
46 *
47 * @param mixed $source Source of the timezone.
48 *
49 * @return \ICanBoogie\Time\Zone
50 */
51 static public function from($source)
52 {
53 if ($source instanceof self)
54 {
55 return $source;
56 }
57 else if ($source instanceof \DateTimeZone)
58 {
59 $source = $source->getName();
60 }
61
62 $source = (string) $source;
63
64 if (empty(self::$cache[$source]))
65 {
66 self::$cache[$source] = new static($source);
67 }
68
69 return self::$cache[$source];
70 }
71
72 /**
73 * The name of the timezone.
74 *
75 * Note: This variable is only used to provide information during debugging.
76 *
77 * @var string
78 */
79 private $name;
80
81 /**
82 * Location of the timezone.
83 *
84 * @var TimeZoneLocation
85 */
86 private $location;
87
88 /**
89 * Initializes the {@link $name} property.
90 *
91 * @param string $timezone
92 */
93 public function __construct($timezone)
94 {
95 parent::__construct($timezone);
96
97 $this->name = $this->getName();
98 }
99
100 /**
101 * Returns the {@link $location}, {@link $name} and {@link $offset} properties.
102 *
103 * @throws PropertyNotDefined in attempt to get an unsupported property.
104 */
105 public function __get($property)
106 {
107 switch ($property)
108 {
109 case 'location':
110
111 if (!$this->location)
112 {
113 $this->location = TimeZoneLocation::from($this);
114 }
115
116 return $this->location;
117
118 case 'name':
119
120 return $this->name;
121
122 case 'offset':
123
124 $utc_time = self::$utc_time;
125
126 if (!$utc_time)
127 {
128 self::$utc_time = $utc_time = new \DateTime('now', new \DateTimeZone('utc'));
129 }
130
131 return $this->getOffset($utc_time);
132 }
133
134 if (class_exists('ICanBoogie\PropertyNotDefined'))
135 {
136 throw new PropertyNotDefined(array($property, $this));
137 }
138 else
139 {
140 throw new \RuntimeException("Property no defined: $property.");
141 }
142 }
143
144 /**
145 * Returns the name of the timezone.
146 *
147 * @return string
148 */
149 public function __toString()
150 {
151 return $this->name;
152 }
153 }