PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/tine20/library/qCal/lib/qCal/Timezone.php

https://gitlab.com/rsilveira1987/Expresso
PHP | 352 lines | 142 code | 64 blank | 146 comment | 16 complexity | a4bdba0d137ab402193a8345a8be0dec MD5 | raw file
  1. <?php
  2. class qCal_Timezone {
  3. /**
  4. * @var string The format to use to output this timezone as a string
  5. * @access protected
  6. */
  7. protected $format = "e";
  8. /**
  9. * @var string The name of the timezone
  10. * @access protected
  11. */
  12. protected $name;
  13. /**
  14. * @var integer The offset (in seconds) of this timezone
  15. * @access protected
  16. */
  17. protected $offsetSeconds;
  18. /**
  19. * @var string The abbreviated name
  20. * @access protected
  21. */
  22. protected $abbreviation;
  23. /**
  24. * @var boolean Whether or not this timezone observes daylight savings (need to figure this out)
  25. * @access protected
  26. */
  27. protected $isDaylightSavings;
  28. /**
  29. * @var array An array of timezone metacharacters that this class allows (see PHP's date() function)
  30. * @access protected
  31. */
  32. protected $formatArray = array();
  33. /**
  34. * @var array An array of timezones that have been registered with the class
  35. * @access protected
  36. * @static
  37. */
  38. protected static $timezones = array();
  39. /**
  40. * Class constructor
  41. * A timezone must have a name, offset (in seconds), and optionsally an abbreviation. Daylight savings defaults to false.
  42. * @param string $name The name of the timezone
  43. * @param integer $offset The offset (in seconds) of this timezone from GMT
  44. * @param string $abbreviation The abbreviated name
  45. * @param boolean $daylightsavings Set to true if this timezone observes daylight savings
  46. * @todo When $abbreviation isn't specified, and $name is a valid pre-defined PHP timezone identifier, use its
  47. * corresponding abbreviation rather than the name itself
  48. * @todo When $offset isn't provided and $name is a valid timezone, use its corresponding offset, but if $name is not
  49. * a valid timezone identifier and no offset is provided, throw an exception
  50. * @todo I don't really know what to do with the daylight savings parameter
  51. */
  52. public function __construct($name, $offset, $abbreviation = null, $daylightsavings = null) {
  53. if (is_null($abbreviation)) $abbreviation = $name;
  54. $this->setName($name)
  55. ->setOffsetSeconds($offset)
  56. ->setAbbreviation($abbreviation)
  57. ->setIsDaylightSavings($daylightsavings);
  58. $this->formatArray = array(
  59. 'e' => $this->getName(),
  60. 'I' => (integer) $this->isDaylightSavings(),
  61. 'O' => $this->getOffsetHours(),
  62. 'P' => $this->getOffset(),
  63. 'T' => $this->getAbbreviation(),
  64. 'Z' => $this->getOffsetSeconds(),
  65. );
  66. }
  67. /**
  68. * @param string $name The name of the timezone
  69. * @return $this
  70. * @access public
  71. */
  72. public function setName($name) {
  73. $this->name = (string) $name;
  74. return $this;
  75. }
  76. /**
  77. * @param integer $offset The offset (in seconds) from GMT
  78. * @return $this
  79. * @access public
  80. */
  81. public function setOffsetSeconds($offset) {
  82. $this->offsetSeconds = (integer) $offset;
  83. return $this;
  84. }
  85. /**
  86. * @param string $abbreviation The abbreviated name of the timezone
  87. * @return $this
  88. * @access public
  89. */
  90. public function setAbbreviation($abbreviation) {
  91. $this->abbreviation = (string) $abbreviation;
  92. return $this;
  93. }
  94. /**
  95. * @param boolean $daylightSavings Whether or not this timezone observes daylight savings
  96. * @return $this
  97. * @access public
  98. */
  99. public function setIsDaylightSavings($daylightSavings = null) {
  100. $this->isDaylightSavings = (boolean) $daylightSavings;
  101. return $this;
  102. }
  103. /**
  104. * Generate a timezone from either an array of parameters, or a timezone
  105. * name such as "America/Los_Angeles".
  106. * @param mixed $timezone A string to be converted to a qCal_Timezone object
  107. * @return qCal_Timezone
  108. * @access public
  109. * @link http://php.net/manual/en/timezones.php A directory of valid timezones
  110. * @todo This method is FUGLY. Rewrite it and make it make sense. This is sort of nonsensical.
  111. */
  112. public static function factory($timezone = null) {
  113. if (is_array($timezone)) {
  114. // remove anything irrelevant
  115. $vals = array_intersect_key($timezone, array_flip(array('name','offsetSeconds','abbreviation','isDaylightSavings')));
  116. if (!array_key_exists("name", $vals)) {
  117. // @todo throw an exception or something
  118. }
  119. if (!array_key_exists("offsetSeconds", $vals)) {
  120. // @todo throw an exception or something
  121. }
  122. $name = $vals['name'];
  123. $offsetSeconds = $vals['offsetSeconds'];
  124. $abbreviation = (array_key_exists('abbreviation', $vals)) ? $vals['abbreviation'] : null;
  125. $isDaylightSavings = (array_key_exists('isDaylightSavings', $vals)) ? $vals['isDaylightSavings'] : null;
  126. $timezone = new qCal_Timezone($name, $offsetSeconds, $abbreviation, $isDaylightSavings);
  127. } else {
  128. // get the timezone information out of the string
  129. $defaultTz = date_default_timezone_get();
  130. if (is_null($timezone)) $timezone = $defaultTz;
  131. // if the timezone being set is invalid, we will get a PHP notice, so error is suppressed here
  132. // @todo It would be more clean and probably more efficient to use php's error handling to throw an exception here...
  133. if (is_string($timezone)) {
  134. @date_default_timezone_set($timezone);
  135. // if the function above didn't work, this will be true
  136. if (date_default_timezone_get() != $timezone) {
  137. // if the timezone requested is registered, use it
  138. if (array_key_exists($timezone, self::$timezones)) {
  139. $timezone = self::$timezones[$timezone];
  140. } else {
  141. // otherwise, throw an exception
  142. throw new qCal_DateTime_Exception_InvalidTimezone("'$timezone' is not a valid timezone.");
  143. }
  144. } else {
  145. // if the timezone specified was a valid (native php) timezone, use it
  146. $name = date("e");
  147. $offset = date("Z");
  148. $abbr = date("T");
  149. $ds = date("I");
  150. $timezone = new qCal_Timezone($name, $offset, $abbr, $ds);
  151. }
  152. }
  153. // now set it back to what it was...
  154. date_default_timezone_set($defaultTz);
  155. }
  156. return $timezone;
  157. }
  158. /**
  159. * Register a timezone object so that it can be referenced by name and qCal
  160. * components will be able to figure out how to apply its offset.
  161. * @param qCal_Timezone $timezone The timezone you want to register
  162. * @access public
  163. * @return void
  164. * @static
  165. */
  166. public static function register(qCal_Timezone $timezone) {
  167. self::$timezones[$timezone->getName()] = $timezone;
  168. }
  169. /**
  170. * Unregisters a timezone by name
  171. * @param string $timezone The name of the timezone to be unregistered
  172. * @return void
  173. * @access public
  174. * @static
  175. */
  176. public static function unregister($timezone) {
  177. unset(self::$timezones[(string) $timezone]);
  178. }
  179. /**
  180. * Return the name of this timezone
  181. * @return string The name of the timezone
  182. * @access public
  183. */
  184. public function getName() {
  185. return $this->name;
  186. }
  187. /**
  188. * Return the offset in hours (+08:00) of this timezone with colon between hours and minutes
  189. * @return string The offset of the timezone
  190. * @access public
  191. */
  192. public function getOffset() {
  193. $seconds = $this->getOffsetSeconds();
  194. $negpos = "+";
  195. if ($seconds < 0) {
  196. $negpos = "-";
  197. }
  198. $hours = (integer) ($seconds / 60 / 60);
  199. $minutes = $hours * 60;
  200. $minutes = ($seconds / 60) - $minutes;
  201. return sprintf("%s%02d:%02d", $negpos, abs($hours), abs($minutes));
  202. }
  203. /**
  204. * Return the offset in hours (+0800) of this timezone
  205. * @return string The offset of the timezone (in hours)
  206. * @access public
  207. */
  208. public function getOffsetHours() {
  209. $seconds = $this->getOffsetSeconds();
  210. $negpos = "+";
  211. if ($seconds < 0) {
  212. $negpos = "-";
  213. }
  214. $hours = (integer) ($seconds / 60 / 60);
  215. $minutes = $hours * 60;
  216. $minutes = ($seconds / 60) - $minutes;
  217. return sprintf("%s%02d%02d", $negpos, abs($hours), abs($minutes));
  218. }
  219. /**
  220. * Return the offset in seconds of this timezone
  221. * @return integer The offset of the timezone
  222. * @access public
  223. */
  224. public function getOffsetSeconds() {
  225. return $this->offsetSeconds;
  226. }
  227. /**
  228. * Return the abbreviated name of this timezone
  229. * @return string The abbreviated name of the timezone
  230. * @access public
  231. */
  232. public function getAbbreviation() {
  233. return $this->abbreviation;
  234. }
  235. /**
  236. * Return true if this timezone observes daylight savings
  237. * @return boolean Whether or not this timezone observes daylight savings
  238. * @access public
  239. */
  240. public function isDaylightSavings() {
  241. return $this->isDaylightSavings;
  242. }
  243. /**
  244. * Set the format that should be used when calling either __toString() or format() without an argument.
  245. * @param string $format
  246. * @return $this
  247. * @link http://php.net/manual/en/timezones.php A directory of valid timezones
  248. * @access public
  249. */
  250. public function setFormat($format) {
  251. $this->format = (string) $format;
  252. return $this;
  253. }
  254. /**
  255. * Return the timezone as a formatted string
  256. * @param string $format The string used to format the object (see PHP's date function)
  257. * @return string The formatted timezone
  258. * @link http://php.net/manual/en/timezones.php A directory of valid timezones
  259. * @access public
  260. */
  261. public function format($format) {
  262. $escape = false;
  263. $meta = str_split($format);
  264. $output = array();
  265. foreach($meta as $char) {
  266. if ($char == '\\') {
  267. $escape = true;
  268. continue;
  269. }
  270. if (!$escape && array_key_exists($char, $this->formatArray)) {
  271. $output[] = $this->formatArray[$char];
  272. } else {
  273. $output[] = $char;
  274. }
  275. // reset this to false after every iteration that wasn't "continued"
  276. $escape = false;
  277. }
  278. return implode($output);
  279. }
  280. /**
  281. * Returns this object formatted as a string (used when this object is printed)
  282. * @return string The formatted timezone
  283. * @access public
  284. */
  285. public function __toString() {
  286. return $this->format($this->format);
  287. }
  288. }