PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/calendar.php

https://github.com/suomaf/gantti
PHP | 724 lines | 512 code | 206 blank | 6 comment | 40 complexity | 4d18876f04abcda908d5777cae7b150f MD5 | raw file
  1. <?php
  2. class CalendarIterator implements Iterator {
  3. private $_ = array();
  4. public function __construct($array=array()) {
  5. $this->_ = $array;
  6. }
  7. function __toString() {
  8. $result = '';
  9. foreach($this->_ as $date) {
  10. $result .= $date . '<br />';
  11. }
  12. return $result;
  13. }
  14. function rewind() {
  15. reset($this->_);
  16. }
  17. function current() {
  18. return current($this->_);
  19. }
  20. function key() {
  21. return key($this->_);
  22. }
  23. function next() {
  24. return next($this->_);
  25. }
  26. function prev() {
  27. return prev($this->_);
  28. }
  29. function valid() {
  30. $key = key($this->_);
  31. $var = ($key !== null && $key !== false);
  32. return $var;
  33. }
  34. function count() {
  35. return count($this->_);
  36. }
  37. function first() {
  38. return array_shift($this->_);
  39. }
  40. function last() {
  41. return array_pop($this->_);
  42. }
  43. function nth($n) {
  44. $values = array_values($this->_);
  45. return isset($values[$n]) ? $values[$n] : null;
  46. }
  47. function indexOf($needle) {
  48. return array_search($needle, array_values($this->_));
  49. }
  50. function toArray() {
  51. return $this->_;
  52. }
  53. function slice($offset=null, $limit=null) {
  54. if($offset === null && $limit === null) return $this;
  55. return new CalendarIterator(array_slice($this->_, $offset, $limit));
  56. }
  57. function limit($limit) {
  58. return $this->slice(0, $limit);
  59. }
  60. }
  61. class CalendarObj {
  62. var $yearINT;
  63. var $monthINT;
  64. var $dayINT;
  65. var $hourINT;
  66. var $minuteINT;
  67. var $secondINT;
  68. var $timestamp = 0;
  69. function __construct($year=false, $month=1, $day=1, $hour=0, $minute=0, $second=0) {
  70. if(!$year) $year = date('Y');
  71. if(!$month) $month = date('m');
  72. if(!$day) $day = date('d');
  73. $this->yearINT = intval($year);
  74. $this->monthINT = intval($month);
  75. $this->dayINT = intval($day);
  76. $this->hourINT = intval($hour);
  77. $this->minuteINT = intval($minute);
  78. $this->secondINT = intval($second);
  79. // convert this to timestamp
  80. $this->timestamp = mktime($hour, $minute, $second, $month, $day, $year);
  81. }
  82. function year($year=false) {
  83. if(!$year) $year = $this->yearINT;
  84. return new CalendarYear($year, 1, 1, 0, 0, 0);
  85. }
  86. function month($month=false) {
  87. if(!$month) $month = $this->monthINT;
  88. return new CalendarMonth($this->yearINT, $month, 1, 0, 0, 0);
  89. }
  90. function day($day=false) {
  91. if(!$day) $day = $this->dayINT;
  92. return new CalendarDay($this->yearINT, $this->monthINT, $day, 0, 0, 0);
  93. }
  94. function hour($hour=false) {
  95. if(!$hour) $hour = $this->hourINT;
  96. return new CalendarHour($this->yearINT, $this->monthINT, $this->dayINT, $hour, 0, 0);
  97. }
  98. function minute($minute=false) {
  99. if(!$minute) $minute = $this->minuteINT;
  100. return new CalendarMinute($this->yearINT, $this->monthINT, $this->dayINT, $this->hourINT, $minute, 0);
  101. }
  102. function second($second=false) {
  103. if(!$second) $second = $this->secondINT;
  104. return new CalendarSecond($this->yearINT, $this->monthINT, $this->dayINT, $this->hourINT, $this->minuteINT, $second);
  105. }
  106. function timestamp() {
  107. return $this->timestamp;
  108. }
  109. function __toString() {
  110. return date('Y-m-d H:i:s', $this->timestamp);
  111. }
  112. function format($format) {
  113. return date($format, $this->timestamp);
  114. }
  115. function iso() {
  116. return date(DATE_ISO, $this->timestamp);
  117. }
  118. function cookie() {
  119. return date(DATE_COOKIE, $this->timestamp);
  120. }
  121. function rss() {
  122. return date(DATE_RSS, $this->timestamp);
  123. }
  124. function atom() {
  125. return date(DATE_ATOM, $this->timestamp);
  126. }
  127. function mysql() {
  128. return date('Y-m-d H:i:s', $this->timestamp);
  129. }
  130. function time() {
  131. return strftime('%T', $this->timestamp);
  132. }
  133. function ampm() {
  134. return strftime('%p', $this->timestamp);
  135. }
  136. function modify($string) {
  137. $ts = (is_int($string)) ? $this->timestamp+$string : strtotime($string, $this->timestamp);
  138. list($year, $month, $day, $hour, $minute, $second) = explode('-', date('Y-m-d-H-i-s', $ts));
  139. return new CalendarDay($year, $month, $day, $hour, $minute, $second);
  140. }
  141. function plus($string) {
  142. $modifier = (is_int($string)) ? $string : '+' . $string;
  143. return $this->modify($modifier);
  144. }
  145. function add($string) {
  146. return $this->plus($string);
  147. }
  148. function minus($string) {
  149. $modifier = (is_int($string)) ? -$string : '-' . $string;
  150. return $this->modify($modifier);
  151. }
  152. function sub($string) {
  153. return $this->minus($string);
  154. }
  155. function dmy() {
  156. return $this->format('d.m.Y');
  157. }
  158. function padded() {
  159. return str_pad($this->int(),2,'0',STR_PAD_LEFT);
  160. }
  161. }
  162. class Calendar {
  163. static $now = 0;
  164. function __construct() {
  165. Calendar::$now = time();
  166. }
  167. function years($start, $end) {
  168. $array = array();
  169. foreach(range($start, $end) as $year) {
  170. $array[] = $this->year($year);
  171. }
  172. return new CalendarIterator($array);
  173. }
  174. function year($year) {
  175. return new CalendarYear($year, 1, 1, 0, 0, 0);
  176. }
  177. function months($year=false) {
  178. $year = new CalendarYear($year, 1, 1, 0, 0, 0);
  179. return $year->months();
  180. }
  181. function month($year, $month) {
  182. return new CalendarMonth($year, $month, 1, 0, 0);
  183. }
  184. function week($year=false, $week=false) {
  185. return new CalendarWeek($year, $week);
  186. }
  187. function days($year=false) {
  188. $year = new CalendarYear($year);
  189. return $year->days();
  190. }
  191. function day($year=false, $month=false, $day=false) {
  192. return new CalendarDay($year, $month, $day);
  193. }
  194. function date() {
  195. $args = func_get_args();
  196. if(count($args) > 1) {
  197. $year = isset($args[0]) ? $args[0] : false;
  198. $month = isset($args[1]) ? $args[1] : 1;
  199. $day = isset($args[2]) ? $args[2] : 1;
  200. $hour = isset($args[3]) ? $args[3] : 0;
  201. $minute = isset($args[4]) ? $args[4] : 0;
  202. $second = isset($args[5]) ? $args[5] : 0;
  203. } else {
  204. if(isset($args[0])) {
  205. $ts = (is_int($args[0])) ? $args[0] : strtotime($args[0]);
  206. } else {
  207. $ts = time();
  208. }
  209. if(!$ts) return false;
  210. list($year, $month, $day, $hour, $minute, $second) = explode('-', date('Y-m-d-H-i-s', $ts));
  211. }
  212. return new CalendarDay($year, $month, $day, $hour, $minute, $second);
  213. }
  214. function today() {
  215. return $this->date('today');
  216. }
  217. function now() {
  218. return $this->today();
  219. }
  220. function tomorrow() {
  221. return $this->date('tomorrow');
  222. }
  223. function yesterday() {
  224. return $this->date('yesterday');
  225. }
  226. }
  227. class CalendarYear extends CalendarObj {
  228. function __toString() {
  229. return $this->format('Y');
  230. }
  231. function int() {
  232. return $this->yearINT;
  233. }
  234. function months() {
  235. $array = array();
  236. foreach(range(1, 12) as $month) {
  237. $array[] = $this->month($month);
  238. }
  239. return new CalendarIterator($array);
  240. }
  241. function month($month=1) {
  242. return new CalendarMonth($this->yearINT, $month);
  243. }
  244. function weeks() {
  245. $array = array();
  246. $weeks = (int)date('W', mktime(0,0,0,12,31,$this->int))+1;
  247. foreach(range(1,$weeks) as $week) {
  248. $array[] = new CalendarWeek($this, $week);
  249. }
  250. return new CalendarIterator($array);
  251. }
  252. function week($week=1) {
  253. return new CalendarWeek($this, $week);
  254. }
  255. function countDays() {
  256. return (int)date('z', mktime(0,0,0,12,31,$this->yearINT))+1;
  257. }
  258. function days() {
  259. $days = $this->countDays();
  260. $array = array();
  261. $ts = false;
  262. for($x=0; $x<$days; $x++) {
  263. $ts = (!$ts) ? $this->timestamp : strtotime('tomorrow', $ts);
  264. $month = date('m', $ts);
  265. $day = date('d', $ts);
  266. $array[] = $this->month($month)->day($day);
  267. }
  268. return new CalendarIterator($array);
  269. }
  270. function next() {
  271. return $this->plus('1year')->year();
  272. }
  273. function prev() {
  274. return $this->minus('1year')->year();
  275. }
  276. function name() {
  277. return $this->int();
  278. }
  279. function firstMonday() {
  280. $cal = new Calendar();
  281. return $cal->date(strtotime('first monday of ' . date('Y', $this->timestamp)));
  282. }
  283. function firstSunday() {
  284. $cal = new Calendar();
  285. return $cal->date(strtotime('first sunday of ' . date('Y', $this->timestamp)));
  286. }
  287. }
  288. class CalendarMonth extends CalendarObj {
  289. function __toString() {
  290. return $this->format('Y-m');
  291. }
  292. function int() {
  293. return $this->monthINT;
  294. }
  295. function weeks($force=false) {
  296. $first = $this->firstDay();
  297. $week = $first->week();
  298. $currentMonth = $this->int();
  299. $nextMonth = $this->next()->int();
  300. $max = ($force) ? $force : 6;
  301. for($x=0; $x<$max; $x++) {
  302. // make sure not to add weeks without a single day in the same month
  303. if(!$force && $x>0 && $week->firstDay()->month()->int() != $currentMonth) break;
  304. $array[] = $week;
  305. // make sure not to add weeks without a single day in the same month
  306. if(!$force && $week->lastDay()->month()->int() != $currentMonth) break;
  307. $week = $week->next();
  308. }
  309. return new CalendarIterator($array);
  310. }
  311. function countDays() {
  312. return date('t', $this->timestamp);
  313. }
  314. function firstDay() {
  315. return new CalendarDay($this->yearINT, $this->monthINT, 1);
  316. }
  317. function lastDay() {
  318. return new CalendarDay($this->yearINT, $this->monthINT, $this->countDays());
  319. }
  320. function days() {
  321. // number of days per month
  322. $days = date('t', $this->timestamp);
  323. $array = array();
  324. $ts = $this->firstDay()->timestamp();
  325. foreach(range(1, $days) as $day) {
  326. $array[] = $this->day($day);
  327. }
  328. return new CalendarIterator($array);
  329. }
  330. function day($day=1) {
  331. return new CalendarDay($this->yearINT, $this->monthINT, $day);
  332. }
  333. function next() {
  334. return $this->plus('1month')->month();
  335. }
  336. function prev() {
  337. return $this->minus('1month')->month();
  338. }
  339. function name() {
  340. return strftime('%B', $this->timestamp);
  341. }
  342. function shortname() {
  343. return strftime('%b', $this->timestamp);
  344. }
  345. }
  346. class CalendarWeek extends CalendarObj {
  347. function __toString() {
  348. return $this->firstDay()->format('Y-m-d') . ' - ' . $this->lastDay()->format('Y-m-d');
  349. }
  350. var $weekINT;
  351. function int() {
  352. return $this->weekINT;
  353. }
  354. function __construct($year=false, $week=false) {
  355. if(!$year) $year = date('Y');
  356. if(!$week) $week = date('W');
  357. $this->yearINT = intval($year);
  358. $this->weekINT = intval($week);
  359. $ts = strtotime('Thursday', strtotime($year . 'W' . $this->padded()));
  360. $monday = strtotime('-3days', $ts);
  361. parent::__construct(date('Y', $monday), date('m', $monday), date('d', $monday), 0, 0, 0);
  362. }
  363. function years() {
  364. $array = array();
  365. $array[] = $this->firstDay()->year();
  366. $array[] = $this->lastDay()->year();
  367. // remove duplicates
  368. $array = array_unique($array);
  369. return new CalendarIterator($array);
  370. }
  371. function months() {
  372. $array = array();
  373. $array[] = $this->firstDay()->month();
  374. $array[] = $this->lastDay()->month();
  375. // remove duplicates
  376. $array = array_unique($array);
  377. return new CalendarIterator($array);
  378. }
  379. function firstDay() {
  380. $cal = new Calendar();
  381. return $cal->date($this->timestamp);
  382. }
  383. function lastDay() {
  384. $first = $this->firstDay();
  385. return $first->plus('6 days');
  386. }
  387. function days() {
  388. $day = $this->firstDay();
  389. $array = array();
  390. for($x=0; $x<7; $x++) {
  391. $array[] = $day;
  392. $day = $day->next();
  393. }
  394. return new CalendarIterator($array);
  395. }
  396. function next() {
  397. $next = strtotime('Thursday next week', $this->timestamp);
  398. $year = date('Y', $next);
  399. $week = date('W', $next);
  400. return new CalendarWeek($year, $week);
  401. }
  402. function prev() {
  403. $prev = strtotime('Monday last week', $this->timestamp);
  404. $year = date('Y', $prev);
  405. $week = date('W', $prev);
  406. return new CalendarWeek($year, $week);
  407. }
  408. }
  409. class CalendarDay extends CalendarObj {
  410. function __toString() {
  411. return $this->format('Y-m-d');
  412. }
  413. function int() {
  414. return $this->dayINT;
  415. }
  416. function week() {
  417. $week = date('W', $this->timestamp);
  418. $year = ($this->monthINT == 1 && $week > 5) ? $this->year()->prev() : $this->year();
  419. return new CalendarWeek($year->int(), $week);
  420. }
  421. function next() {
  422. return $this->plus('1day');
  423. }
  424. function prev() {
  425. return $this->minus('1day');
  426. }
  427. function weekday() {
  428. return date('N', $this->timestamp);
  429. }
  430. function name() {
  431. return strftime('%A', $this->timestamp);
  432. }
  433. function shortname() {
  434. return strftime('%a', $this->timestamp);
  435. }
  436. function isToday() {
  437. $cal = new Calendar();
  438. return $this == $cal->today();
  439. }
  440. function isYesterday() {
  441. $cal = new Calendar();
  442. return $this == $cal->yesterday();
  443. }
  444. function isTomorrow() {
  445. $cal = new Calendar();
  446. return $this == $cal->tomorrow();
  447. }
  448. function isInThePast() {
  449. return ($this->timestamp < Calendar::$now) ? true : false;
  450. }
  451. function isInTheFuture() {
  452. return ($this->timestamp > Calendar::$now) ? true : false;
  453. }
  454. function isWeekend() {
  455. $num = $this->format('w');
  456. return ($num == 6 || $num == 0) ? true : false;
  457. }
  458. function hours() {
  459. $obj = $this;
  460. $array = array();
  461. while($obj->int() == $this->int()) {
  462. $array[] = $obj->hour();
  463. $obj = $obj->plus('1hour');
  464. }
  465. return new CalendarIterator($array);
  466. }
  467. }
  468. class CalendarHour extends CalendarObj {
  469. function int() {
  470. return $this->hourINT;
  471. }
  472. function minutes() {
  473. $obj = $this;
  474. $array = array();
  475. while($obj->hourINT == $this->hourINT) {
  476. $array[] = $obj;
  477. $obj = $obj->plus('1minute')->minute();
  478. }
  479. return new CalendarIterator($array);
  480. }
  481. function next() {
  482. return $this->plus('1hour')->hour();
  483. }
  484. function prev() {
  485. return $this->minus('1hour')->hour();
  486. }
  487. }
  488. class CalendarMinute extends CalendarObj {
  489. function int() {
  490. return $this->minuteINT;
  491. }
  492. function seconds() {
  493. $obj = $this;
  494. $array = array();
  495. while($obj->minuteINT == $this->minuteINT) {
  496. $array[] = $obj;
  497. $obj = $obj->plus('1second')->second();
  498. }
  499. return new CalendarIterator($array);
  500. }
  501. function next() {
  502. return $this->plus('1minute')->minute();
  503. }
  504. function prev() {
  505. return $this->minus('1minute')->minute();
  506. }
  507. }
  508. class CalendarSecond extends CalendarObj {
  509. function int() {
  510. return $this->secondINT;
  511. }
  512. function next() {
  513. return $this->plus('1second')->second();
  514. }
  515. function prev() {
  516. return $this->minus('1second')->second();
  517. }
  518. }