PageRenderTime 45ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Calendar/DateTimeUtils.php

https://github.com/sequoiar/Kurogo-Mobile-Web
PHP | 209 lines | 153 code | 26 blank | 30 comment | 38 complexity | d684f067cef714f9fb9009f4f65bc9a9 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /**
  3. * @package ExternalData
  4. * @subpackage Calendar
  5. */
  6. interface CalendarInterface {
  7. public function getEventsInRange(TimeRange $range=null, $limit=null);
  8. }
  9. /**
  10. * TimeRange: class describing a time interval.
  11. * @package ExternalData
  12. * @subpackage Calendar
  13. */
  14. class TimeRange {
  15. protected $start;
  16. protected $end;
  17. public function __toString()
  18. {
  19. $string = date("D M j g:i", $this->get_start());
  20. if ( $this->get_end()) {
  21. if ( date('a', $this->get_start()) != date('a', $this->get_end())) {
  22. $string .= date(' a', $this->get_start());
  23. }
  24. if ( date('Ymd', $this->get_start()) != date('Ymd', $this->get_end())) {
  25. $string .= date(" - D M j g:i a", $this->get_end());
  26. } else {
  27. $string .= date("-g:i a", $this->get_end());
  28. }
  29. } else {
  30. $string .= date(' a', $this->get_start());
  31. }
  32. return $string;
  33. }
  34. protected static $precedence = Array(
  35. 's', //second
  36. 'i', //minute
  37. 'G', 'g', 'H', 'h', //hour
  38. 'A', 'a', //half day
  39. 'D', 'l', 'N', 'w', //weekday
  40. 'd', 'j', 'S', //monthday
  41. 'z', //yearday
  42. 'W', //week
  43. 'F', 'M', 'm', 'n', 't', //month
  44. 'Y', 'y', //year
  45. );
  46. public function get_start() {
  47. return $this->start;
  48. }
  49. public function set_start($start) {
  50. $this->start = $start;
  51. }
  52. public function get_end() {
  53. return $this->end;
  54. }
  55. public function set_end($end) {
  56. $this->end = $end;
  57. }
  58. public function format($format, $compress=TRUE) {
  59. if ($this->start == $this->end) {
  60. return date($format, $this->start);
  61. } else {
  62. $token_types = Array();
  63. // the letters in this regex are the parameters for date()
  64. preg_match_all('/([AaDdFGgHhijlMmNnoSstWwYyz])/', $format, $matches);
  65. foreach ($matches[1] as $match) {
  66. $prec = array_search($match, self::$precedence);
  67. $token_types[$prec] = $match;
  68. }
  69. krsort($token_types);
  70. $left = Array(); // string to show left of hyphen
  71. $right = Array(); // string to show right of hyphen
  72. if ($compress) {
  73. // iterate through tokens in decreasing grain size
  74. // until a tokens are different for start and end date
  75. while (list($prec, $token_type) = each ($token_types)) {
  76. $start = date($token_type, $this->start);
  77. $end = date($token_type, $this->end);
  78. $left[strpos($format, $token_type)] = $start;
  79. if ($start != $end) {
  80. $right[strpos($format, $token_type)] = $end;
  81. break;
  82. }
  83. }
  84. }
  85. // iterate through the rest of the array
  86. while (list($prec, $token_type) = each ($token_types)) {
  87. $start = date($token_type, $this->start);
  88. $end = date($token_type, $this->end);
  89. $left[strpos($format, $token_type)] = $start;
  90. $right[strpos($format, $token_type)] = $end;
  91. }
  92. $formatted = '';
  93. $buffer = '';
  94. for ($i = 0; $i < strlen($format); $i++) {
  95. if (array_key_exists($i, $left)) {
  96. if (array_key_exists($i, $right)) {
  97. $buffer .= $right[$i];
  98. } elseif ($buffer != '') {
  99. $formatted = rtrim($formatted, ' ,') . '-' . $buffer;
  100. //$formatted .= '-' . $buffer;
  101. $buffer = '';
  102. }
  103. $formatted .= $left[$i];
  104. } else {
  105. $formatted .= substr($format, $i, 1);
  106. if ($buffer != '') {
  107. $buffer .= substr($format, $i, 1);
  108. }
  109. }
  110. }
  111. if ($buffer != '') {
  112. $formatted = rtrim($formatted, ' ,') . '-' . $buffer;
  113. //$formatted .= '-' . $buffer;
  114. }
  115. return $formatted;
  116. }
  117. }
  118. /**
  119. * Returns whether any part of the 2 ranges overlap
  120. */
  121. public function overlaps(TimeRange $range) {
  122. if ($range->get_start() >= $this->end) return FALSE;
  123. elseif ($range->get_end() <= $this->start) return FALSE;
  124. else return TRUE;
  125. }
  126. /**
  127. * Returns whether the parameter is completely contained by the object
  128. */
  129. public function contains(TimeRange $range) {
  130. if (!$this->overlaps($range)) return FALSE;
  131. elseif ($range->get_start() < $this->start) return FALSE;
  132. elseif ($range->get_end() > $this->end) return FALSE;
  133. else return TRUE;
  134. }
  135. /**
  136. * Returns whether the parameter completely surrounds the object
  137. */
  138. public function contained_by(TimeRange $range) {
  139. if (!$this->overlaps($range)) return FALSE;
  140. elseif ($range->get_start() > $this->start) return FALSE;
  141. elseif ($range->get_end() < $this->end) return FALSE;
  142. else return TRUE;
  143. }
  144. public function contains_point($time) {
  145. return ($this->start <= $time && $this->end > $time);
  146. }
  147. public function __construct($start, $end=NULL) {
  148. if ($end === NULL) { // instantaneous event
  149. $end = $start;
  150. } elseif ($start > $end) {
  151. throw new Exception('argument 1 (start time) must be <= argument 2 (end time)');
  152. }
  153. $this->start = $start;
  154. $this->end = $end;
  155. }
  156. }
  157. /**
  158. * DayRange: child class of TimeRange describing a full day
  159. * @package ExternalData
  160. * @subpackage Calendar
  161. */
  162. class DayRange extends TimeRange {
  163. public function __toString()
  164. {
  165. $string = strftime("%a %b %e", $this->get_start());
  166. if ( ($this->get_end() - $this->get_start()) > 86400) {
  167. $string .= strftime("- %a %b %e", $this->get_end());
  168. }
  169. return $string;
  170. }
  171. public function __construct($start, $end=null, $tzid=NULL) {
  172. if (is_null($end)) {
  173. $end = $start;
  174. }
  175. // use mktime which uses system time zone if tzid is blank or is the same as system time zone TODO: what happens if it's different?
  176. if (!$tzid || $tzid == date_default_timezone_get()) {
  177. $this->start = mktime(0, 0, 0, date('m', $start), date('d', $start), date('Y', $start));
  178. $this->end = mktime(23, 59, 59, date('m', $end), date('d', $end), date('Y', $end));
  179. } else {
  180. throw new Exception("Timezone set ($tzid), but is not the same as system time zone (" . date_default_timezone_get() . "). This case needs to be handled");
  181. }
  182. }
  183. }