PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/p093_includes/Date.php

https://bitbucket.org/rlm3/rlm3_dev
PHP | 398 lines | 321 code | 77 blank | 0 comment | 35 complexity | 04152e5f174f223a426f47a956aa9fc4 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. class Date {
  3. protected $_time;
  4. protected $_workingDaysCalendar = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri');
  5. const DAYS = 'day';
  6. const MINUTES = 'minute';
  7. const HOURS = 'hour';
  8. public static function create()
  9. {
  10. return new Date();
  11. }
  12. public function __construct($date = null)
  13. {
  14. if (!$date)
  15. {
  16. $this->_time = time();
  17. return;
  18. }
  19. if (is_string($date))
  20. {
  21. $this->_time = strtotime($date);
  22. }
  23. elseif ($date instanceof self)
  24. {
  25. $this->_time = $date->getTime();
  26. }
  27. elseif (is_numeric ((int) $date))
  28. {
  29. $this->_time = $date;
  30. }
  31. }
  32. public static function reverse($date)
  33. {
  34. $dateTime = preg_split('/\s/', trim($date));
  35. if (count($dateTime) == 0) {
  36. return $date;
  37. }
  38. $date = array_shift($dateTime);
  39. $time = '';
  40. if (!empty($dateTime)) {
  41. $time = array_shift($dateTime);
  42. }
  43. $dateTime = implode('-', array_reverse(preg_split('/\//', $date)));
  44. if (!empty($time)) {
  45. $dateTime .= " $time";
  46. }
  47. return $dateTime;
  48. }
  49. public static function format($format, $date = true) {
  50. if ($date === true) {
  51. $date = time();
  52. }
  53. if (is_int($date)) {
  54. return date($format, $date);
  55. }
  56. return date($format, strtotime($date));
  57. }
  58. public function getFormatted($format)
  59. {
  60. return Date::format($format, $this->getTime());
  61. }
  62. public static function now($includeTime = true)
  63. {
  64. if ($includeTime)
  65. {
  66. return date('Y-m-d H:i:s');
  67. }
  68. return date('Y-m-d');
  69. }
  70. public static function tomorrow($includeTime = true)
  71. {
  72. $format = 'Y-m-d H:i:s';
  73. if (!$includeTime)
  74. {
  75. $format = 'Y-m-d';
  76. }
  77. return date($format, strtotime("+1 day"));
  78. }
  79. public static function dayAfterTomorrow($includeTime = true)
  80. {
  81. $format = 'Y-m-d H:i:s';
  82. if (!$includeTime)
  83. {
  84. $format = 'Y-m-d';
  85. }
  86. return date($format, strtotime("+2 day"));
  87. }
  88. public function grossDaysUntil($until, $options = array())
  89. {
  90. $default = array('workingSchedule' => array('Mon' => array('8:00', '17:00'),
  91. 'Tue' => array('8:00', '17:00'),
  92. 'Wed' => array('8:00', '17:00'),
  93. 'Thu' => array('8:00', '17:00'),
  94. 'Fri' => array('8:00', '17:00'),
  95. 'Sat' => array('8:00', '17:00'),
  96. 'Sun' => array('8:00', '17:00')),
  97. 'hoursPerDay' => 9,
  98. 'lunchBreakHours' => 0);
  99. $options = array_merge($default, $options);
  100. return $this->workingDaysUntil($until, $options);
  101. }
  102. public function daysUntil($until, $exclude = array())
  103. {
  104. $secondsPerDay = 86400;
  105. $until = strtotime(date('Y-m-d', strtotime($until)));
  106. $time = strtotime(date("Y-m-d", $this->_time));
  107. return ($until - $time) / $secondsPerDay;
  108. }
  109. public function toSqlDate()
  110. {
  111. return date('Y-m-d H:i:s', $this->_time);
  112. }
  113. public function hoursUntil($until)
  114. {
  115. return (strtotime($until) - $this->_time) / 3600;
  116. }
  117. public function workingDaysUntil($until, $options = array())
  118. {
  119. if ($this->_time == strtotime($until))
  120. {
  121. return 0;
  122. }
  123. $default = array('workingSchedule' => array('Mon' => array('8:00', '17:00'),
  124. 'Tue' => array('8:00', '17:00'),
  125. 'Wed' => array('8:00', '17:00'),
  126. 'Thu' => array('8:00', '17:00'),
  127. 'Fri' => array('8:00', '17:00'),
  128. 'Sat' => array('8:00', '12:00')),
  129. 'hoursPerDay' => 9,
  130. 'lunchBreakHours' => 0);
  131. $options = array_merge($default, $options);
  132. $workingSchedule = $options['workingSchedule'];
  133. $currentTimestamp = strtotime(date('Y-m-d', $this->_time));
  134. $endTimestamp = strtotime(date('Y-m-d', strtotime($until)));
  135. $dayCount = 0;
  136. while ($currentTimestamp <= $endTimestamp)
  137. {
  138. if (!empty($workingSchedule[date('D', $currentTimestamp)]))
  139. {
  140. $currentSchedule = $workingSchedule[date('D', $currentTimestamp)];
  141. $d = new Date($currentSchedule[0]);
  142. $hoursPerDay = $d->hoursUntil($currentSchedule[1]);
  143. if ($hoursPerDay > 6)
  144. {
  145. $hoursPerDay -= $options['lunchBreakHours'];
  146. }
  147. $dayCount += $hoursPerDay / $options['hoursPerDay'];
  148. }
  149. $currentTimestamp = strtotime('+1 day', $currentTimestamp);
  150. }
  151. $dates = array('start' => $this->toSqlDate(), 'end' => $until);
  152. foreach($dates as $tag => $date)
  153. {
  154. $timestamp = strtotime($date);
  155. $weekDay = date('D', $timestamp);
  156. if (!empty($workingSchedule[$weekDay]))
  157. {
  158. $dayStartTime = strtotime($workingSchedule[$weekDay][0]);
  159. $dayEndTime = strtotime($workingSchedule[$weekDay][1]);
  160. $dateTime = strtotime(date('H:i', strtotime($date)));
  161. if ($dateTime < $dayStartTime)
  162. {
  163. $dateTime = $dayStartTime;
  164. }
  165. elseif ($dateTime > $dayEndTime)
  166. {
  167. $dateTime = $dayEndTime;
  168. }
  169. $diff = $dateTime - $dayStartTime;
  170. if ($tag == 'end')
  171. {
  172. $diff = $dayEndTime - $dateTime;
  173. }
  174. if ($diff > 0)
  175. {
  176. $dayCount -= (($diff) / (60 * 60)) / $options['hoursPerDay'];
  177. }
  178. }
  179. }
  180. return round($dayCount, 2);
  181. }
  182. public function __toString()
  183. {
  184. return $this->toSqlDate();
  185. }
  186. public function isSQLValid($date)
  187. {
  188. $tokens = preg_split('/-/', $date);
  189. if (count($tokens) != 3)
  190. {
  191. return false;
  192. }
  193. $year = (int) array_shift($tokens);
  194. $month = (int) array_shift($tokens);
  195. $day = (int) array_shift($tokens);
  196. if ($year <= 0 || $month <= 0 || $day <= 0)
  197. {
  198. return false;
  199. }
  200. return checkdate($month, $day, $year);
  201. }
  202. public function dayOfWeek($mondayFirst = true)
  203. {
  204. return (int) date('N', $this->_time);
  205. }
  206. public function isWorkingDay()
  207. {
  208. $currentDay = ucfirst(date('D', $this->_time));
  209. return in_array($currentDay, $this->_workingDaysCalendar);
  210. }
  211. public function nextDay()
  212. {
  213. return new Date(strtotime('+1 day', $this->_time));
  214. }
  215. public function prevDay()
  216. {
  217. return new Date(strtotime('-1 day', $this->_time));
  218. }
  219. public function nextMonth()
  220. {
  221. return new Date(strtotime('+1 month', $this->_time));
  222. }
  223. public function workingDayOfMonth()
  224. {
  225. if (!$this->isWorkingDay())
  226. {
  227. return -1;
  228. }
  229. $current = $this->_time;
  230. $count = 1;
  231. while(((int) date('j', $current)) > 1)
  232. {
  233. $current = strtotime('-1 day', $current);
  234. $currentDay = new Date($current);
  235. if ($currentDay->isWorkingDay())
  236. {
  237. $count++;
  238. }
  239. }
  240. return $count;
  241. }
  242. public function getWorkingDaysOfMonthCount()
  243. {
  244. $count = 0;
  245. $current = new Date(date('Y-m-01', $this->_time));
  246. $current->setWorkingDaysCalendar($this->_workingDaysCalendar);
  247. $end = new Date(date('Y-m-t', $this->_time));
  248. while ($current->getTime(false) <= $end->getTime(false))
  249. {
  250. if ($current->isWorkingDay())
  251. {
  252. $count++;
  253. }
  254. $current = new Date($current->nextDay());
  255. $current->setWorkingDaysCalendar($this->_workingDaysCalendar);
  256. }
  257. return $count;
  258. }
  259. public function getWorkDayOfMonthIndex()
  260. {
  261. $count = 0;
  262. $current = new Date(date('Y-m-01', $this->_time));
  263. $current->setWorkingDaysCalendar($this->_workingDaysCalendar);
  264. while ($current->getTime(false) <= $this->getTime(false))
  265. {
  266. if ($current->isWorkingDay())
  267. {
  268. $count++;
  269. }
  270. $current = new Date($current->nextDay());
  271. $current->setWorkingDaysCalendar($this->_workingDaysCalendar);
  272. }
  273. return $count;
  274. }
  275. public function getTime($includeTime = true)
  276. {
  277. if (!$includeTime)
  278. {
  279. return strtotime(date('Y-m-d', $this->_time));
  280. }
  281. return $this->_time;
  282. }
  283. public function getDate()
  284. {
  285. return new Date(date('Y-m-d', $this->_time));
  286. }
  287. public function toFormat($format)
  288. {
  289. return date($format, $this->_time);
  290. }
  291. public function add($value, $unit = self::DAYS)
  292. {
  293. if ($value > 0)
  294. {
  295. $this->_time = strtotime("+{$value} {$unit}", $this->_time);
  296. return $this;
  297. }
  298. $this->_time = strtotime("-{$value} {$unit}", $this->_time);
  299. return $this;
  300. }
  301. public function compare(self $date)
  302. {
  303. if ($this->getTime() > $date->getTime())
  304. {
  305. return 1;
  306. }
  307. elseif ($this->getTime() < $date->getTime())
  308. {
  309. return -1;
  310. }
  311. return 0;
  312. }
  313. public function setTime($time)
  314. {
  315. $this->_time = $time;
  316. }
  317. public function setWorkingDaysCalendar($workingDaysCalendar)
  318. {
  319. $this->_workingDaysCalendar = $workingDaysCalendar;
  320. }
  321. }