Span.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. <?php
  2. // vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Leandro Lucarella <llucax@php.net> |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Span.php,v 1.4 2003/04/30 03:56:26 llucax Exp $
  20. //
  21. require_once 'Date.php';
  22. require_once 'Date/Calc.php';
  23. /**
  24. * Non Numeric Separated Values (NNSV) Input Format.
  25. *
  26. * Input format guessed from something like this:
  27. * days<sep>hours<sep>minutes<sep>seconds
  28. * Where <sep> is any quantity of non numeric chars. If no values are
  29. * given, time span is set to zero, if one value is given, it's used for
  30. * hours, if two values are given it's used for hours and minutes and if
  31. * three values are given, it's used for hours, minutes and seconds.<br>
  32. * Examples:<br>
  33. * '' -> 0, 0, 0, 0 (days, hours, minutes, seconds)<br>
  34. * '12' -> 0, 12, 0, 0
  35. * '12.30' -> 0, 12, 30, 0<br>
  36. * '12:30:18' -> 0, 12, 30, 18<br>
  37. * '3-12-30-18' -> 3, 12, 30, 18<br>
  38. * '3 days, 12-30-18' -> 3, 12, 30, 18<br>
  39. * '12:30 with 18 secs' -> 0, 12, 30, 18<br>
  40. *
  41. * @const int
  42. */
  43. define('DATE_SPAN_INPUT_FORMAT_NNSV', 1);
  44. /**
  45. * Default time format when converting to a string.
  46. *
  47. * @global string
  48. */
  49. $_DATE_SPAN_FORMAT = '%C';
  50. /**
  51. * Default time format when converting from a string.
  52. *
  53. * @global mixed
  54. */
  55. $_DATE_SPAN_INPUT_FORMAT = DATE_SPAN_INPUT_FORMAT_NNSV;
  56. /**
  57. * Generic time span handling class for PEAR.
  58. *
  59. * @package Date
  60. * @author Leandro Lucarella <llucax@php.net>
  61. * @version $Revision: 1.4 $
  62. * @since 1.4
  63. * @todo Get and set default local input and output formats?
  64. * @access public
  65. */
  66. class Date_Span {
  67. /**
  68. * @var int
  69. */
  70. var $day;
  71. /**
  72. * @var int
  73. */
  74. var $hour;
  75. /**
  76. * @var int
  77. */
  78. var $minute;
  79. /**
  80. * @var int
  81. */
  82. var $second;
  83. /**
  84. * Constructor.
  85. *
  86. * Creates the time span object calling the set() method.
  87. *
  88. * @param mixed $time Time span expression.
  89. * @param mixed $format Format string to set it from a string or the
  90. * second date set it from a date diff.
  91. *
  92. * @see set()
  93. * @access public
  94. */
  95. function Date_Span($time = 0, $format = null)
  96. {
  97. $this->set($time, $format);
  98. }
  99. /**
  100. * Set the time span to a new value in a 'smart' way.
  101. *
  102. * Sets the time span depending on the argument types, calling
  103. * to the appropriate setFromXxx() method.
  104. *
  105. * @param mixed $time Time span expression.
  106. * @param mixed $format Format string to set it from a string or the
  107. * second date set it from a date diff.
  108. *
  109. * @return bool true on success.
  110. *
  111. * @see setFromObject()
  112. * @see setFromArray()
  113. * @see setFromString()
  114. * @see setFromSeconds()
  115. * @see setFromDateDiff()
  116. * @access public
  117. */
  118. function set($time = 0, $format = null)
  119. {
  120. if (is_a($time, 'date_span')) {
  121. return $this->copy($time);
  122. } elseif (is_a($time, 'date') and is_a($format, 'date')) {
  123. return $this->setFromDateDiff($time, $format);
  124. } elseif (is_array($time)) {
  125. return $this->setFromArray($time);
  126. } elseif (is_string($time)) {
  127. return $this->setFromString($time, $format);
  128. } elseif (is_int($time)) {
  129. return $this->setFromSeconds($time);
  130. } else {
  131. return $this->setFromSeconds(0);
  132. }
  133. }
  134. /**
  135. * Set the time span from an array.
  136. *
  137. * Set the time span from an array. Any value can be a float (but it
  138. * has no sense in seconds), for example array(23.5, 20, 0) is
  139. * interpreted as 23 hours, .5*60 + 20 = 50 minutes and 0 seconds.
  140. *
  141. * @param array $time Items are counted from right to left. First
  142. * item is for seconds, second for minutes, third
  143. * for hours and fourth for days. If there are
  144. * less items than 4, zero (0) is assumed for the
  145. * absent values.
  146. *
  147. * @return bool True on success.
  148. *
  149. * @access public
  150. */
  151. function setFromArray($time)
  152. {
  153. if (!is_array($time)) {
  154. return false;
  155. }
  156. $tmp1 = new Date_Span;
  157. if (!$tmp1->setFromSeconds(@array_pop($time))) {
  158. return false;
  159. }
  160. $tmp2 = new Date_Span;
  161. if (!$tmp2->setFromMinutes(@array_pop($time))) {
  162. return false;
  163. }
  164. $tmp1->add($tmp2);
  165. if (!$tmp2->setFromHours(@array_pop($time))) {
  166. return false;
  167. }
  168. $tmp1->add($tmp2);
  169. if (!$tmp2->setFromDays(@array_pop($time))) {
  170. return false;
  171. }
  172. $tmp1->add($tmp2);
  173. return $this->copy($tmp1);
  174. }
  175. /**
  176. * Set the time span from a string based on an input format.
  177. *
  178. * Set the time span from a string based on an input format. This is
  179. * some like a mix of format() method and sscanf() PHP function. The
  180. * error checking and validation of this function is very primitive,
  181. * so you should be carefull when using it with unknown $time strings.
  182. * With this method you are assigning day, hour, minute and second
  183. * values, and the last values are used. This means that if you use
  184. * something like setFromString('10, 20', '%H, %h') your time span
  185. * would be 20 hours long. Allways remember that this method set
  186. * <b>all</b> the values, so if you had a $time span 30 minutes long
  187. * and you make $time->setFromString('20 hours', '%H hours'), $time
  188. * span would be 20 hours long (and not 20 hours and 30 minutes).
  189. * Input format options:<br>
  190. * <code>%C</code> Days with time, same as "%D, %H:%M:%S".<br>
  191. * <code>%d</code> Total days as a float number
  192. * (2 days, 12 hours = 2.5 days).<br>
  193. * <code>%D</code> Days as a decimal number.<br>
  194. * <code>%e</code> Total hours as a float number
  195. * (1 day, 2 hours, 30 minutes = 26.5 hours).<br>
  196. * <code>%f</code> Total minutes as a float number
  197. * (2 minutes, 30 seconds = 2.5 minutes).<br>
  198. * <code>%g</code> Total seconds as a decimal number
  199. * (2 minutes, 30 seconds = 90 seconds).<br>
  200. * <code>%h</code> Hours as decimal number.<br>
  201. * <code>%H</code> Hours as decimal number limited to 2 digits.<br>
  202. * <code>%m</code> Minutes as a decimal number.<br>
  203. * <code>%M</code> Minutes as a decimal number limited to 2 digits.<br>
  204. * <code>%n</code> Newline character (\n).<br>
  205. * <code>%p</code> Either 'am' or 'pm' depending on the time. If 'pm'
  206. * is detected it adds 12 hours to the resulting time
  207. * span (without any checks). This is case
  208. * insensitive.<br>
  209. * <code>%r</code> Time in am/pm notation, same as "%H:%M:%S %p".<br>
  210. * <code>%R</code> Time in 24-hour notation, same as "%H:%M".<br>
  211. * <code>%s</code> Seconds as a decimal number.<br>
  212. * <code>%S</code> Seconds as a decimal number limited to 2 digits.<br>
  213. * <code>%t</code> Tab character (\t).<br>
  214. * <code>%T</code> Current time equivalent, same as "%H:%M:%S".<br>
  215. * <code>%%</code> Literal '%'.<br>
  216. *
  217. * @param string $time String from where to get the time span
  218. * information.
  219. * @param string $format Format string.
  220. *
  221. * @return bool True on success.
  222. *
  223. * @access public
  224. */
  225. function setFromString($time, $format = null)
  226. {
  227. if (is_null($format)) {
  228. $format = $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
  229. }
  230. // If format is a string, it parses the string format.
  231. if (is_string($format)) {
  232. $str = '';
  233. $vars = array();
  234. $pm = 'am';
  235. $day = $hour = $minute = $second = 0;
  236. for ($i = 0; $i < strlen($format); $i++) {
  237. $char = $format{$i};
  238. if ($char == '%') {
  239. $nextchar = $format{++$i};
  240. switch ($nextchar) {
  241. case 'c':
  242. $str .= '%d, %d:%d:%d';
  243. array_push(
  244. $vars, 'day', 'hour', 'minute', 'second');
  245. break;
  246. case 'C':
  247. $str .= '%d, %2d:%2d:%2d';
  248. array_push(
  249. $vars, 'day', 'hour', 'minute', 'second');
  250. break;
  251. case 'd':
  252. $str .= '%f';
  253. array_push($vars, 'day');
  254. break;
  255. case 'D':
  256. $str .= '%d';
  257. array_push($vars, 'day');
  258. break;
  259. case 'e':
  260. $str .= '%f';
  261. array_push($vars, 'hour');
  262. break;
  263. case 'f':
  264. $str .= '%f';
  265. array_push($vars, 'minute');
  266. break;
  267. case 'g':
  268. $str .= '%f';
  269. array_push($vars, 'second');
  270. break;
  271. case 'h':
  272. $str .= '%d';
  273. array_push($vars, 'hour');
  274. break;
  275. case 'H':
  276. $str .= '%2d';
  277. array_push($vars, 'hour');
  278. break;
  279. case 'm':
  280. $str .= '%d';
  281. array_push($vars, 'minute');
  282. break;
  283. case 'M':
  284. $str .= '%2d';
  285. array_push($vars, 'minute');
  286. break;
  287. case 'n':
  288. $str .= "\n";
  289. break;
  290. case 'p':
  291. $str .= '%2s';
  292. array_push($vars, 'pm');
  293. break;
  294. case 'r':
  295. $str .= '%2d:%2d:%2d %2s';
  296. array_push(
  297. $vars, 'hour', 'minute', 'second', 'pm');
  298. break;
  299. case 'R':
  300. $str .= '%2d:%2d';
  301. array_push($vars, 'hour', 'minute');
  302. break;
  303. case 's':
  304. $str .= '%d';
  305. array_push($vars, 'second');
  306. break;
  307. case 'S':
  308. $str .= '%2d';
  309. array_push($vars, 'second');
  310. break;
  311. case 't':
  312. $str .= "\t";
  313. break;
  314. case 'T':
  315. $str .= '%2d:%2d:%2d';
  316. array_push($vars, 'hour', 'minute', 'second');
  317. break;
  318. case '%':
  319. $str .= "%";
  320. break;
  321. default:
  322. $str .= $char . $nextchar;
  323. }
  324. } else {
  325. $str .= $char;
  326. }
  327. }
  328. $vals = sscanf($time, $str);
  329. foreach ($vals as $i => $val) {
  330. if (is_null($val)) {
  331. return false;
  332. }
  333. $$vars[$i] = $val;
  334. }
  335. if (strcasecmp($pm, 'pm') == 0) {
  336. $hour += 12;
  337. } elseif (strcasecmp($pm, 'am') != 0) {
  338. return false;
  339. }
  340. $this->setFromArray(array($day, $hour, $minute, $second));
  341. // If format is a integer, it uses a predefined format
  342. // detection method.
  343. } elseif (is_integer($format)) {
  344. switch ($format) {
  345. case DATE_SPAN_INPUT_FORMAT_NNSV:
  346. $time = preg_split('/\D+/', $time);
  347. switch (count($time)) {
  348. case 0:
  349. return $this->setFromArray(
  350. array(0, 0, 0, 0));
  351. case 1:
  352. return $this->setFromArray(
  353. array(0, $time[0], 0, 0));
  354. case 2:
  355. return $this->setFromArray(
  356. array(0, $time[0], $time[1], 0));
  357. case 3:
  358. return $this->setFromArray(
  359. array(0, $time[0], $time[1], $time[2]));
  360. default:
  361. return $this->setFromArray($time);
  362. }
  363. break;
  364. }
  365. }
  366. return false;
  367. }
  368. /**
  369. * Set the time span from a total number of seconds.
  370. *
  371. * @param int $seconds Total number of seconds.
  372. *
  373. * @return bool True on success.
  374. *
  375. * @access public
  376. */
  377. function setFromSeconds($seconds)
  378. {
  379. if ($seconds < 0) {
  380. return false;
  381. }
  382. $sec = intval($seconds);
  383. $min = floor($sec / 60);
  384. $hour = floor($min / 60);
  385. $day = intval(floor($hour / 24));
  386. $this->second = $sec % 60;
  387. $this->minute = $min % 60;
  388. $this->hour = $hour % 24;
  389. $this->day = $day;
  390. return true;
  391. }
  392. /**
  393. * Set the time span from a total number of minutes.
  394. *
  395. * @param float $minutes Total number of minutes.
  396. *
  397. * @return bool True on success.
  398. *
  399. * @access public
  400. */
  401. function setFromMinutes($minutes)
  402. {
  403. return $this->setFromSeconds(round($minutes * 60));
  404. }
  405. /**
  406. * Set the time span from a total number of hours.
  407. *
  408. * @param float $hours Total number of hours.
  409. *
  410. * @return bool True on success.
  411. *
  412. * @access public
  413. */
  414. function setFromHours($hours)
  415. {
  416. return $this->setFromSeconds(round($hours * 3600));
  417. }
  418. /**
  419. * Set the time span from a total number of days.
  420. *
  421. * @param float $days Total number of days.
  422. *
  423. * @return bool True on success.
  424. *
  425. * @access public
  426. */
  427. function setFromDays($days)
  428. {
  429. return $this->setFromSeconds(round($days * 86400));
  430. }
  431. /**
  432. * Set the span from the elapsed time between two dates.
  433. *
  434. * Set the span from the elapsed time between two dates. The time span
  435. * is allways positive, so the date's order is not important.
  436. *
  437. * @param object Date $date1 First Date.
  438. * @param object Date $date2 Second Date.
  439. *
  440. * @return bool True on success.
  441. *
  442. * @access public
  443. */
  444. function setFromDateDiff($date1, $date2)
  445. {
  446. if (!is_a($date1, 'date') or !is_a($date2, 'date')) {
  447. return false;
  448. }
  449. $date1->toUTC();
  450. $date2->toUTC();
  451. if ($date1->after($date2)) {
  452. list($date1, $date2) = array($date2, $date1);
  453. }
  454. $days = Date_Calc::dateDiff(
  455. $date1->getDay(), $date1->getMonth(), $date1->getYear(),
  456. $date2->getDay(), $date2->getMonth(), $date2->getYear()
  457. );
  458. $hours = $date2->getHour() - $date1->getHour();
  459. $mins = $date2->getMinute() - $date1->getMinute();
  460. $secs = $date2->getSecond() - $date1->getSecond();
  461. $this->setFromSeconds(
  462. $days * 86400 + $hours * 3600 + $mins * 60 + $secs
  463. );
  464. return true;
  465. }
  466. /**
  467. * Set the time span from another time object.
  468. *
  469. * @param object Date_Span $time Source time span object.
  470. *
  471. * @return bool True on success.
  472. *
  473. * @access public
  474. */
  475. function copy($time)
  476. {
  477. if (is_a($time, 'date_span')) {
  478. $this->second = $time->second;
  479. $this->minute = $time->minute;
  480. $this->hour = $time->hour;
  481. $this->day = $time->day;
  482. return true;
  483. } else {
  484. return false;
  485. }
  486. }
  487. /**
  488. * Time span pretty printing (similar to Date::format()).
  489. *
  490. * Formats the time span in the given format, similar to
  491. * strftime() and Date::format().<br>
  492. * <br>
  493. * Formatting options:<br>
  494. * <code>%C</code> Days with time, same as "%D, %H:%M:%S".<br>
  495. * <code>%d</code> Total days as a float number
  496. * (2 days, 12 hours = 2.5 days).<br>
  497. * <code>%D</code> Days as a decimal number.<br>
  498. * <code>%e</code> Total hours as a float number
  499. * (1 day, 2 hours, 30 minutes = 26.5 hours).<br>
  500. * <code>%E</code> Total hours as a decimal number
  501. * (1 day, 2 hours, 40 minutes = 26 hours).<br>
  502. * <code>%f</code> Total minutes as a float number
  503. * (2 minutes, 30 seconds = 2.5 minutes).<br>
  504. * <code>%F</code> Total minutes as a decimal number
  505. * (1 hour, 2 minutes, 40 seconds = 62 minutes).<br>
  506. * <code>%g</code> Total seconds as a decimal number
  507. * (2 minutes, 30 seconds = 90 seconds).<br>
  508. * <code>%h</code> Hours as decimal number (0 to 23).<br>
  509. * <code>%H</code> Hours as decimal number (00 to 23).<br>
  510. * <code>%i</code> Hours as decimal number on 12-hour clock
  511. * (1 to 12).<br>
  512. * <code>%I</code> Hours as decimal number on 12-hour clock
  513. * (01 to 12).<br>
  514. * <code>%m</code> Minutes as a decimal number (0 to 59).<br>
  515. * <code>%M</code> Minutes as a decimal number (00 to 59).<br>
  516. * <code>%n</code> Newline character (\n).<br>
  517. * <code>%p</code> Either 'am' or 'pm' depending on the time.<br>
  518. * <code>%P</code> Either 'AM' or 'PM' depending on the time.<br>
  519. * <code>%r</code> Time in am/pm notation, same as "%I:%M:%S %p".<br>
  520. * <code>%R</code> Time in 24-hour notation, same as "%H:%M".<br>
  521. * <code>%s</code> Seconds as a decimal number (0 to 59).<br>
  522. * <code>%S</code> Seconds as a decimal number (00 to 59).<br>
  523. * <code>%t</code> Tab character (\t).<br>
  524. * <code>%T</code> Current time equivalent, same as "%H:%M:%S".<br>
  525. * <code>%%</code> Literal '%'.<br>
  526. *
  527. * @param string $format The format string for returned time span.
  528. *
  529. * @return string The time span in specified format.
  530. *
  531. * @access public
  532. */
  533. function format($format = null)
  534. {
  535. if (is_null($format)) {
  536. $format = $GLOBALS['_DATE_SPAN_FORMAT'];
  537. }
  538. $output = '';
  539. for ($i = 0; $i < strlen($format); $i++) {
  540. $char = $format{$i};
  541. if ($char == '%') {
  542. $nextchar = $format{++$i};
  543. switch ($nextchar) {
  544. case 'C':
  545. $output .= sprintf(
  546. '%d, %02d:%02d:%02d',
  547. $this->day,
  548. $this->hour,
  549. $this->minute,
  550. $this->second
  551. );
  552. break;
  553. case 'd':
  554. $output .= $this->toDays();
  555. break;
  556. case 'D':
  557. $output .= $this->day;
  558. break;
  559. case 'e':
  560. $output .= $this->toHours();
  561. break;
  562. case 'E':
  563. $output .= floor($this->toHours());
  564. break;
  565. case 'f':
  566. $output .= $this->toMinutes();
  567. break;
  568. case 'F':
  569. $output .= floor($this->toMinutes());
  570. break;
  571. case 'g':
  572. $output .= $this->toSeconds();
  573. break;
  574. case 'h':
  575. $output .= $this->hour;
  576. break;
  577. case 'H':
  578. $output .= sprintf('%02d', $this->hour);
  579. break;
  580. case 'i':
  581. $hour =
  582. ($this->hour + 1) > 12 ?
  583. $this->hour - 12 :
  584. $this->hour;
  585. $output .= ($hour == 0) ? 12 : $hour;
  586. break;
  587. case 'I':
  588. $hour =
  589. ($this->hour + 1) > 12 ?
  590. $this->hour - 12 :
  591. $this->hour;
  592. $output .= sprintf('%02d', $hour==0 ? 12 : $hour);
  593. break;
  594. case 'm':
  595. $output .= $this->minute;
  596. break;
  597. case 'M':
  598. $output .= sprintf('%02d',$this->minute);
  599. break;
  600. case 'n':
  601. $output .= "\n";
  602. break;
  603. case 'p':
  604. $output .= $this->hour >= 12 ? 'pm' : 'am';
  605. break;
  606. case 'P':
  607. $output .= $this->hour >= 12 ? 'PM' : 'AM';
  608. break;
  609. case 'r':
  610. $hour =
  611. ($this->hour + 1) > 12 ?
  612. $this->hour - 12 :
  613. $this->hour;
  614. $output .= sprintf(
  615. '%02d:%02d:%02d %s',
  616. $hour==0 ? 12 : $hour,
  617. $this->minute,
  618. $this->second,
  619. $this->hour >= 12 ? 'pm' : 'am'
  620. );
  621. break;
  622. case 'R':
  623. $output .= sprintf(
  624. '%02d:%02d', $this->hour, $this->minute
  625. );
  626. break;
  627. case 's':
  628. $output .= $this->second;
  629. break;
  630. case 'S':
  631. $output .= sprintf('%02d', $this->second);
  632. break;
  633. case 't':
  634. $output .= "\t";
  635. break;
  636. case 'T':
  637. $output .= sprintf(
  638. '%02d:%02d:%02d',
  639. $this->hour, $this->minute, $this->second
  640. );
  641. break;
  642. case '%':
  643. $output .= "%";
  644. break;
  645. default:
  646. $output .= $char . $nextchar;
  647. }
  648. } else {
  649. $output .= $char;
  650. }
  651. }
  652. return $output;
  653. }
  654. /**
  655. * Convert time span to seconds.
  656. *
  657. * @return int Time span as an integer number of seconds.
  658. *
  659. * @access public
  660. */
  661. function toSeconds()
  662. {
  663. return $this->day * 86400 + $this->hour * 3600 +
  664. $this->minute * 60 + $this->second;
  665. }
  666. /**
  667. * Convert time span to minutes.
  668. *
  669. * @return float Time span as a decimal number of minutes.
  670. *
  671. * @access public
  672. */
  673. function toMinutes()
  674. {
  675. return $this->day * 1440 + $this->hour * 60 + $this->minute +
  676. $this->second / 60;
  677. }
  678. /**
  679. * Convert time span to hours.
  680. *
  681. * @return float Time span as a decimal number of hours.
  682. *
  683. * @access public
  684. */
  685. function toHours()
  686. {
  687. return $this->day * 24 + $this->hour + $this->minute / 60 +
  688. $this->second / 3600;
  689. }
  690. /**
  691. * Convert time span to days.
  692. *
  693. * @return float Time span as a decimal number of days.
  694. *
  695. * @access public
  696. */
  697. function toDays()
  698. {
  699. return $this->day + $this->hour / 24 + $this->minute / 1440 +
  700. $this->second / 86400;
  701. }
  702. /**
  703. * Adds a time span.
  704. *
  705. * @param object Date_Span $time Time span to add.
  706. *
  707. * @access public
  708. */
  709. function add($time)
  710. {
  711. return $this->setFromSeconds(
  712. $this->toSeconds() + $time->toSeconds()
  713. );
  714. }
  715. /**
  716. * Subtracts a time span.
  717. *
  718. * Subtracts a time span. If the time span to subtract is larger
  719. * than the original, the result is zero (there's no sense in
  720. * negative time spans).
  721. *
  722. * @param object Date_Span $time Time span to subtract.
  723. *
  724. * @access public
  725. */
  726. function subtract($time)
  727. {
  728. $sub = $this->toSeconds() - $time->toSeconds();
  729. if ($sub < 0) {
  730. $this->setFromSeconds(0);
  731. } else {
  732. $this->setFromSeconds($sub);
  733. }
  734. }
  735. /**
  736. * Tells if time span is equal to $time.
  737. *
  738. * @param object Date_Span $time Time span to compare to.
  739. *
  740. * @return bool True if the time spans are equal.
  741. *
  742. * @access public
  743. */
  744. function equal($time)
  745. {
  746. return $this->toSeconds() == $time->toSeconds();
  747. }
  748. /**
  749. * Tells if this time span is greater or equal than $time.
  750. *
  751. * @param object Date_Span $time Time span to compare to.
  752. *
  753. * @return bool True if this time span is greater or equal than $time.
  754. *
  755. * @access public
  756. */
  757. function greaterEqual($time)
  758. {
  759. return $this->toSeconds() >= $time->toSeconds();
  760. }
  761. /**
  762. * Tells if this time span is lower or equal than $time.
  763. *
  764. * @param object Date_Span $time Time span to compare to.
  765. *
  766. * @return bool True if this time span is lower or equal than $time.
  767. *
  768. * @access public
  769. */
  770. function lowerEqual($time)
  771. {
  772. return $this->toSeconds() <= $time->toSeconds();
  773. }
  774. /**
  775. * Tells if this time span is greater than $time.
  776. *
  777. * @param object Date_Span $time Time span to compare to.
  778. *
  779. * @return bool True if this time span is greater than $time.
  780. *
  781. * @access public
  782. */
  783. function greater($time)
  784. {
  785. return $this->toSeconds() > $time->toSeconds();
  786. }
  787. /**
  788. * Tells if this time span is lower than $time.
  789. *
  790. * @param object Date_Span $time Time span to compare to.
  791. *
  792. * @return bool True if this time span is lower than $time.
  793. *
  794. * @access public
  795. */
  796. function lower($time)
  797. {
  798. return $this->toSeconds() < $time->toSeconds();
  799. }
  800. /**
  801. * Compares two time spans.
  802. *
  803. * Compares two time spans. Suitable for use in sorting functions.
  804. *
  805. * @param object Date_Span $time1 The first time span.
  806. * @param object Date_Span $time2 The second time span.
  807. *
  808. * @return int 0 if the time spans are equal, -1 if time1 is lower
  809. * than time2, 1 if time1 is greater than time2.
  810. *
  811. * @static
  812. * @access public
  813. */
  814. function compare($time1, $time2)
  815. {
  816. if ($time1->equal($time2)) {
  817. return 0;
  818. } elseif ($time1->lower($time2)) {
  819. return -1;
  820. } else {
  821. return 1;
  822. }
  823. }
  824. /**
  825. * Tells if the time span is empty (zero length).
  826. *
  827. * @return bool True is it's empty.
  828. */
  829. function isEmpty()
  830. {
  831. return !$this->day && !$this->hour && !$this->minute && !$this->second;
  832. }
  833. /**
  834. * Set the default input format.
  835. *
  836. * @param mixed $format New default input format.
  837. *
  838. * @return mixed Previous default input format.
  839. *
  840. * @static
  841. */
  842. function setDefaultInputFormat($format)
  843. {
  844. $old = $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
  845. $GLOBALS['_DATE_SPAN_INPUT_FORMAT'] = $format;
  846. return $old;
  847. }
  848. /**
  849. * Get the default input format.
  850. *
  851. * @return mixed Default input format.
  852. *
  853. * @static
  854. */
  855. function getDefaultInputFormat()
  856. {
  857. return $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
  858. }
  859. /**
  860. * Set the default format.
  861. *
  862. * @param mixed $format New default format.
  863. *
  864. * @return mixed Previous default format.
  865. *
  866. * @static
  867. */
  868. function setDefaultFormat($format)
  869. {
  870. $old = $GLOBALS['_DATE_SPAN_FORMAT'];
  871. $GLOBALS['_DATE_SPAN_FORMAT'] = $format;
  872. return $old;
  873. }
  874. /**
  875. * Get the default format.
  876. *
  877. * @return mixed Default format.
  878. *
  879. * @static
  880. */
  881. function getDefaultFormat()
  882. {
  883. return $GLOBALS['_DATE_SPAN_FORMAT'];
  884. }
  885. /**
  886. * Returns a copy of the object (workarround for PHP5 forward compatibility).
  887. *
  888. * @return object Date_Span Copy of the object.
  889. */
  890. function __clone() {
  891. $c = get_class($this);
  892. $s = new $c;
  893. $s->day = $this->day;
  894. $s->hour = $this->hour;
  895. $s->minute = $this->minute;
  896. $s->second = $this->second;
  897. return $s;
  898. }
  899. }
  900. ?>