PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tine20/library/qCal/lib/qCal/DateTime.php

https://gitlab.com/rsilveira1987/Expresso
PHP | 258 lines | 96 code | 44 blank | 118 comment | 16 complexity | b725516959abc605f0f07632b3b17677 MD5 | raw file
  1. <?php
  2. /**
  3. * Date/Time Object
  4. *
  5. * In order to perform all the complex date/time based math and logic required to
  6. * implement the iCalendar spec, we need a complex date/time class. This class represents
  7. * a specific point in time, including the time. Internally it makes use of qCal_Date and
  8. * qCal_Time. If only a date or only a time needs to be represented, then one of those
  9. * classes should be used.
  10. *
  11. * @package qCal
  12. * @subpackage qCal_DateTime
  13. * @copyright Luke Visinoni (luke.visinoni@gmail.com)
  14. * @author Luke Visinoni (luke.visinoni@gmail.com)
  15. * @license GNU Lesser General Public License
  16. */
  17. class qCal_DateTime {
  18. /**
  19. * @var qCal_Date An object that represents the date
  20. */
  21. protected $date;
  22. /**
  23. * @var qCal_Time An object that represents the time
  24. */
  25. protected $time;
  26. /**
  27. * @var string The default string representation of datetime is a direct
  28. * correlation to the date function's "c" metacharacter
  29. */
  30. protected $format = "Y-m-d\TH:i:sP";
  31. /**
  32. * Class constructor
  33. * @param integer $year
  34. * @param integer $month
  35. * @param integer $day
  36. * @param integer $hour
  37. * @param integer $minute
  38. * @param integer $second
  39. * @param mixed $timezone Either a qCal_Timezone object or a string representing one
  40. * @param boolean $rollover Set to true to be able to specify things like
  41. * 100 seconds and have it roll over to one minute, forty seconds
  42. * @access public
  43. * @todo Make this default to "now"
  44. * @todo It is possible that the timezone could put the date back (or forward?) a day. This does not account for that
  45. */
  46. public function __construct($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null, $rollover = null) {
  47. $date = new qCal_Date($year, $month, $day, $rollover);
  48. $time = new qCal_Time($hour, $minute, $second, $timezone, $rollover);
  49. $this->setDate($date);
  50. $this->setTime($time);
  51. }
  52. /**
  53. * Generate a datetime object from a string (much like PHP's strtotime function)
  54. * @param string A date/time string to convert into a qCal_DateTime object
  55. * @param mixed Either a qCal_Timezone object or a string representing one
  56. * @return qCal_DateTime
  57. * @access public
  58. * @todo Should this accept qCal_Date and qCal_DateTime objects?
  59. */
  60. public static function factory($datetime, $timezone = null) {
  61. if (substr($datetime,0,4)=='TZID') {
  62. // Handle DateTime with Timezones
  63. $buffer = explode(';', $datetime, 2);
  64. $datetime = $buffer[1];
  65. $buffer = explode('=', $buffer[0], 2);
  66. $timezone = $buffer[1];
  67. }
  68. if (is_null($timezone) || !($timezone instanceof qCal_Timezone)) {
  69. // @todo Make sure this doesn't cause any issues
  70. // detect if we're working with a UTC string like "19970101T180000Z", where the Z means use UTC time
  71. if (strtolower(substr($datetime, -1)) == "z") {
  72. $timezone = "UTC";
  73. }
  74. $timezone = qCal_Timezone::factory($timezone);
  75. }
  76. // get the default timezone so we can set it back to it later
  77. $tz = date_default_timezone_get();
  78. // set the timezone to GMT temporarily
  79. date_default_timezone_set("GMT");
  80. // handles unix timestamp
  81. if (is_integer($datetime) || ctype_digit((string) $datetime)) {
  82. $timestamp = $datetime;
  83. } else {
  84. // handles just about any string representation of date/time (strtotime)
  85. if (is_string($datetime) || empty($datetime)) {
  86. if (!$timestamp = strtotime($datetime)) {
  87. // if unix timestamp can't be created throw an exception
  88. throw new qCal_DateTime_Exception("Invalid or ambiguous date/time string passed to qCal_DateTime::factory()");
  89. }
  90. }
  91. }
  92. if (!isset($timestamp)) {
  93. throw new qCal_DateTime_Exception("Could not generate a qCal_DateTime object.");
  94. }
  95. list($year, $month, $day, $hour, $minute, $second) = explode("|", gmdate("Y|m|d|H|i|s", $timestamp));
  96. // set the timezone back to what it was
  97. date_default_timezone_set($tz);
  98. return new qCal_DateTime($year, $month, $day, $hour, $minute, $second, $timezone);
  99. }
  100. /**
  101. * Set the date component
  102. * @param qCal_Date The date component portion of this object
  103. * @return $this
  104. * @access protected
  105. */
  106. protected function setDate(qCal_Date $date) {
  107. $this->date = $date;
  108. return $this;
  109. }
  110. /**
  111. * Set the time component
  112. * @param qCal_Time The time component portion of this object
  113. * @return $this
  114. * @access protected
  115. */
  116. protected function setTime(qCal_Time $time) {
  117. $this->time = $time;
  118. return $this;
  119. }
  120. /**
  121. * Get time portion as object
  122. * @return qCal_Time The time component portion of this object
  123. * @access public
  124. */
  125. public function getTime() {
  126. return $this->time;
  127. }
  128. /**
  129. * Get date portion as object
  130. * @return qCal_Date The date component portion of this object
  131. * @access public
  132. */
  133. public function getDate() {
  134. return $this->date;
  135. }
  136. /**
  137. * Get unix timestamp
  138. * @param boolean $useOffset Set to true if you want the timestamp to
  139. * consider the timezone's offset
  140. * @return integer The unix timestamp of this object
  141. * @access public
  142. */
  143. public function getUnixTimestamp($useOffset = true) {
  144. return $this->date->getUnixTimestamp() + $this->time->getTimestamp($useOffset);
  145. }
  146. /**
  147. * Set the format to use when outputting as a string
  148. * @param string $format The format that is to be used when this object is
  149. * converted to a string. Use the same metacharacters that are used in PHP's date function
  150. * @return $this
  151. * @access public
  152. */
  153. public function setFormat($format) {
  154. $this->format = (string) $format;
  155. return $this;
  156. }
  157. /**
  158. * Format the date/time using PHP's date() function's meta-characters
  159. * @param string $format Use the PHP date() function's meta-characters to convert this object to a string
  160. * @return string The formatted date/time string
  161. * @access public
  162. * @todo It's obvious I need to find a better solution to formatting since I have repeated this method
  163. * in three classes now...
  164. */
  165. public function format($format) {
  166. $escape = false;
  167. $meta = str_split($format);
  168. $output = array();
  169. foreach($meta as $char) {
  170. if ($char == '\\') {
  171. $escape = true;
  172. continue;
  173. }
  174. if (!$escape && $this->convertChar($char) != $char) {
  175. $output[] = $this->convertChar($char);
  176. } else {
  177. $output[] = $char;
  178. }
  179. // reset this to false after every iteration that wasn't "continued"
  180. $escape = false;
  181. }
  182. return implode($output);
  183. }
  184. /**
  185. * Converts a metacharacter into its date/time counter-part.
  186. * @param string $char The metacharacter that is to be converted
  187. * @return string The converted date/time value
  188. * @access public
  189. */
  190. protected function convertChar($char) {
  191. $char = $this->date->format($char);
  192. $char = $this->time->format($char);
  193. $char = $this->time->getTimezone()->format($char);
  194. return $char;
  195. }
  196. /**
  197. * Output date/time as string
  198. * @return string The string representation of this object
  199. * @access public
  200. */
  201. public function __toString() {
  202. return $this->format($this->format);
  203. }
  204. /**
  205. * Get date/time as UTC
  206. * @param boolean $humanReadable Set to true if you want the result to be a more human-oriented format
  207. * @return string The UTC-formatted date/time
  208. * @access public
  209. */
  210. public function getUtc($humanReadable = false) {
  211. if ($humanReadable) return gmdate('Y-m-d', $this->date->getUnixTimestamp()) . gmdate('\TH:i:s\Z', $this->time->getTimestamp());
  212. else return gmdate('Ymd', $this->date->getUnixTimestamp()) . gmdate('\THis\Z', $this->time->getTimestamp());
  213. }
  214. }