commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / civicrm / packages / Date / Span.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
3
4 // {{{ Header
5
6 /**
7 * Generic time span handling class for PEAR
8 *
9 * PHP versions 4 and 5
10 *
11 * LICENSE:
12 *
13 * Copyright (c) 1997-2005 Leandro Lucarella, Pierre-Alain Joye
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted under the terms of the BSD License.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 * @category Date and Time
33 * @package Date
34 * @author Leandro Lucarella <llucax@php.net>
35 * @author Pierre-Alain Joye <pajoye@php.net>
36 * @copyright 1997-2006 Leandro Lucarella, Pierre-Alain Joye
37 * @license http://www.opensource.org/licenses/bsd-license.php
38 * BSD License
39 * @version CVS: $Id: Span.php,v 1.9 2006/11/21 17:38:15 firman Exp $
40 * @link http://pear.php.net/package/Date
41 * @since File available since Release 1.4
42 */
43
44 // }}}
45 // {{{ Includes
46
47 /**
48 * Get the Date class
49 */
50 require_once 'Date.php';
51
52 /**
53 * Get the Date_Calc class
54 */
55 require_once 'Date/Calc.php';
56
57 // }}}
58 // {{{ Constants
59
60 /**
61 * Non Numeric Separated Values (NNSV) Input Format.
62 *
63 * Input format guessed from something like this:
64 * days<sep>hours<sep>minutes<sep>seconds
65 * Where <sep> is any quantity of non numeric chars. If no values are
66 * given, time span is set to zero, if one value is given, it's used for
67 * hours, if two values are given it's used for hours and minutes and if
68 * three values are given, it's used for hours, minutes and seconds.<br>
69 * Examples:<br>
70 * '' -> 0, 0, 0, 0 (days, hours, minutes, seconds)<br>
71 * '12' -> 0, 12, 0, 0
72 * '12.30' -> 0, 12, 30, 0<br>
73 * '12:30:18' -> 0, 12, 30, 18<br>
74 * '3-12-30-18' -> 3, 12, 30, 18<br>
75 * '3 days, 12-30-18' -> 3, 12, 30, 18<br>
76 * '12:30 with 18 secs' -> 0, 12, 30, 18<br>
77 *
78 * @const int
79 */
80 define('DATE_SPAN_INPUT_FORMAT_NNSV', 1);
81
82 // }}}
83 // {{{ Global Variables
84
85 /**
86 * Default time format when converting to a string.
87 *
88 * @global string
89 */
90 $GLOBALS['_DATE_SPAN_FORMAT'] = '%C';
91
92 /**
93 * Default time format when converting from a string.
94 *
95 * @global mixed
96 */
97 $GLOBALS['_DATE_SPAN_INPUT_FORMAT'] = DATE_SPAN_INPUT_FORMAT_NNSV;
98
99 // }}}
100 // {{{ Class: Date_Span
101
102 /**
103 * Generic time span handling class for PEAR
104 *
105 * @author Leandro Lucarella <llucax@php.net>
106 * @author Pierre-Alain Joye <pajoye@php.net>
107 * @copyright 1997-2006 Leandro Lucarella, Pierre-Alain Joye
108 * @license http://www.opensource.org/licenses/bsd-license.php
109 * BSD License
110 * @version Release: 1.4.7
111 * @link http://pear.php.net/package/Date
112 * @since Class available since Release 1.4
113 */
114 class Date_Span
115 {
116 // {{{ Properties
117
118 /**
119 * @var int
120 */
121 var $day;
122
123 /**
124 * @var int
125 */
126 var $hour;
127
128 /**
129 * @var int
130 */
131 var $minute;
132
133 /**
134 * @var int
135 */
136 var $second;
137
138 // }}}
139 // {{{ Constructor
140
141 /**
142 * Constructor.
143 *
144 * Creates the time span object calling the set() method.
145 *
146 * @param mixed $time Time span expression.
147 * @param mixed $format Format string to set it from a string or the
148 * second date set it from a date diff.
149 *
150 * @see set()
151 * @access public
152 */
153 function Date_Span($time = 0, $format = null)
154 {
155 $this->set($time, $format);
156 }
157
158 // }}}
159 // {{{ set()
160
161 /**
162 * Set the time span to a new value in a 'smart' way.
163 *
164 * Sets the time span depending on the argument types, calling
165 * to the appropriate setFromXxx() method.
166 *
167 * @param mixed $time Time span expression.
168 * @param mixed $format Format string to set it from a string or the
169 * second date set it from a date diff.
170 *
171 * @return bool true on success.
172 *
173 * @see setFromObject()
174 * @see setFromArray()
175 * @see setFromString()
176 * @see setFromSeconds()
177 * @see setFromDateDiff()
178 * @access public
179 */
180 function set($time = 0, $format = null)
181 {
182 if (is_a($time, 'date_span')) {
183 return $this->copy($time);
184 } elseif (is_a($time, 'date') and is_a($format, 'date')) {
185 return $this->setFromDateDiff($time, $format);
186 } elseif (is_array($time)) {
187 return $this->setFromArray($time);
188 } elseif (is_string($time)) {
189 return $this->setFromString($time, $format);
190 } elseif (is_int($time)) {
191 return $this->setFromSeconds($time);
192 } else {
193 return $this->setFromSeconds(0);
194 }
195 }
196
197 // }}}
198 // {{{ setFromArray()
199
200 /**
201 * Set the time span from an array.
202 *
203 * Set the time span from an array. Any value can be a float (but it
204 * has no sense in seconds), for example array(23.5, 20, 0) is
205 * interpreted as 23 hours, .5*60 + 20 = 50 minutes and 0 seconds.
206 *
207 * @param array $time Items are counted from right to left. First
208 * item is for seconds, second for minutes, third
209 * for hours and fourth for days. If there are
210 * less items than 4, zero (0) is assumed for the
211 * absent values.
212 *
213 * @return bool True on success.
214 *
215 * @access public
216 */
217 function setFromArray($time)
218 {
219 if (!is_array($time)) {
220 return false;
221 }
222 $tmp1 = new Date_Span;
223 if (!$tmp1->setFromSeconds(@array_pop($time))) {
224 return false;
225 }
226 $tmp2 = new Date_Span;
227 if (!$tmp2->setFromMinutes(@array_pop($time))) {
228 return false;
229 }
230 $tmp1->add($tmp2);
231 if (!$tmp2->setFromHours(@array_pop($time))) {
232 return false;
233 }
234 $tmp1->add($tmp2);
235 if (!$tmp2->setFromDays(@array_pop($time))) {
236 return false;
237 }
238 $tmp1->add($tmp2);
239 return $this->copy($tmp1);
240 }
241
242 // }}}
243 // {{{ setFromString()
244
245 /**
246 * Set the time span from a string based on an input format.
247 *
248 * Set the time span from a string based on an input format. This is
249 * some like a mix of format() method and sscanf() PHP function. The
250 * error checking and validation of this function is very primitive,
251 * so you should be carefull when using it with unknown $time strings.
252 * With this method you are assigning day, hour, minute and second
253 * values, and the last values are used. This means that if you use
254 * something like setFromString('10, 20', '%H, %h') your time span
255 * would be 20 hours long. Allways remember that this method set
256 * <b>all</b> the values, so if you had a $time span 30 minutes long
257 * and you make $time->setFromString('20 hours', '%H hours'), $time
258 * span would be 20 hours long (and not 20 hours and 30 minutes).
259 * Input format options:<br>
260 * <code>%C</code> Days with time, same as "%D, %H:%M:%S".<br>
261 * <code>%d</code> Total days as a float number
262 * (2 days, 12 hours = 2.5 days).<br>
263 * <code>%D</code> Days as a decimal number.<br>
264 * <code>%e</code> Total hours as a float number
265 * (1 day, 2 hours, 30 minutes = 26.5 hours).<br>
266 * <code>%f</code> Total minutes as a float number
267 * (2 minutes, 30 seconds = 2.5 minutes).<br>
268 * <code>%g</code> Total seconds as a decimal number
269 * (2 minutes, 30 seconds = 90 seconds).<br>
270 * <code>%h</code> Hours as decimal number.<br>
271 * <code>%H</code> Hours as decimal number limited to 2 digits.<br>
272 * <code>%m</code> Minutes as a decimal number.<br>
273 * <code>%M</code> Minutes as a decimal number limited to 2 digits.<br>
274 * <code>%n</code> Newline character (\n).<br>
275 * <code>%p</code> Either 'am' or 'pm' depending on the time. If 'pm'
276 * is detected it adds 12 hours to the resulting time
277 * span (without any checks). This is case
278 * insensitive.<br>
279 * <code>%r</code> Time in am/pm notation, same as "%H:%M:%S %p".<br>
280 * <code>%R</code> Time in 24-hour notation, same as "%H:%M".<br>
281 * <code>%s</code> Seconds as a decimal number.<br>
282 * <code>%S</code> Seconds as a decimal number limited to 2 digits.<br>
283 * <code>%t</code> Tab character (\t).<br>
284 * <code>%T</code> Current time equivalent, same as "%H:%M:%S".<br>
285 * <code>%%</code> Literal '%'.<br>
286 *
287 * @param string $time String from where to get the time span
288 * information.
289 * @param string $format Format string.
290 *
291 * @return bool True on success.
292 *
293 * @access public
294 */
295 function setFromString($time, $format = null)
296 {
297 if (is_null($format)) {
298 $format = $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
299 }
300 // If format is a string, it parses the string format.
301 if (is_string($format)) {
302 $str = '';
303 $vars = array();
304 $pm = 'am';
305 $day = $hour = $minute = $second = 0;
306 for ($i = 0; $i < strlen($format); $i++) {
307 $char = $format{$i};
308 if ($char == '%') {
309 $nextchar = $format{++$i};
310 switch ($nextchar) {
311 case 'c':
312 $str .= '%d, %d:%d:%d';
313 array_push(
314 $vars, 'day', 'hour', 'minute', 'second');
315 break;
316 case 'C':
317 $str .= '%d, %2d:%2d:%2d';
318 array_push(
319 $vars, 'day', 'hour', 'minute', 'second');
320 break;
321 case 'd':
322 $str .= '%f';
323 array_push($vars, 'day');
324 break;
325 case 'D':
326 $str .= '%d';
327 array_push($vars, 'day');
328 break;
329 case 'e':
330 $str .= '%f';
331 array_push($vars, 'hour');
332 break;
333 case 'f':
334 $str .= '%f';
335 array_push($vars, 'minute');
336 break;
337 case 'g':
338 $str .= '%f';
339 array_push($vars, 'second');
340 break;
341 case 'h':
342 $str .= '%d';
343 array_push($vars, 'hour');
344 break;
345 case 'H':
346 $str .= '%2d';
347 array_push($vars, 'hour');
348 break;
349 case 'm':
350 $str .= '%d';
351 array_push($vars, 'minute');
352 break;
353 case 'M':
354 $str .= '%2d';
355 array_push($vars, 'minute');
356 break;
357 case 'n':
358 $str .= "\n";
359 break;
360 case 'p':
361 $str .= '%2s';
362 array_push($vars, 'pm');
363 break;
364 case 'r':
365 $str .= '%2d:%2d:%2d %2s';
366 array_push(
367 $vars, 'hour', 'minute', 'second', 'pm');
368 break;
369 case 'R':
370 $str .= '%2d:%2d';
371 array_push($vars, 'hour', 'minute');
372 break;
373 case 's':
374 $str .= '%d';
375 array_push($vars, 'second');
376 break;
377 case 'S':
378 $str .= '%2d';
379 array_push($vars, 'second');
380 break;
381 case 't':
382 $str .= "\t";
383 break;
384 case 'T':
385 $str .= '%2d:%2d:%2d';
386 array_push($vars, 'hour', 'minute', 'second');
387 break;
388 case '%':
389 $str .= "%";
390 break;
391 default:
392 $str .= $char . $nextchar;
393 }
394 } else {
395 $str .= $char;
396 }
397 }
398 $vals = sscanf($time, $str);
399 foreach ($vals as $i => $val) {
400 if (is_null($val)) {
401 return false;
402 }
403 $$vars[$i] = $val;
404 }
405 if (strcasecmp($pm, 'pm') == 0) {
406 $hour += 12;
407 } elseif (strcasecmp($pm, 'am') != 0) {
408 return false;
409 }
410 $this->setFromArray(array($day, $hour, $minute, $second));
411 // If format is a integer, it uses a predefined format
412 // detection method.
413 } elseif (is_integer($format)) {
414 switch ($format) {
415 case DATE_SPAN_INPUT_FORMAT_NNSV:
416 $time = preg_split('/\D+/', $time);
417 switch (count($time)) {
418 case 0:
419 return $this->setFromArray(
420 array(0, 0, 0, 0));
421 case 1:
422 return $this->setFromArray(
423 array(0, $time[0], 0, 0));
424 case 2:
425 return $this->setFromArray(
426 array(0, $time[0], $time[1], 0));
427 case 3:
428 return $this->setFromArray(
429 array(0, $time[0], $time[1], $time[2]));
430 default:
431 return $this->setFromArray($time);
432 }
433 break;
434 }
435 }
436 return false;
437 }
438
439 // }}}
440 // {{{ setFromSeconds()
441
442 /**
443 * Set the time span from a total number of seconds.
444 *
445 * @param int $seconds Total number of seconds.
446 *
447 * @return bool True on success.
448 *
449 * @access public
450 */
451 function setFromSeconds($seconds)
452 {
453 if ($seconds < 0) {
454 return false;
455 }
456 $sec = intval($seconds);
457 $min = floor($sec / 60);
458 $hour = floor($min / 60);
459 $day = intval(floor($hour / 24));
460 $this->second = $sec % 60;
461 $this->minute = $min % 60;
462 $this->hour = $hour % 24;
463 $this->day = $day;
464 return true;
465 }
466
467 // }}}
468 // {{{ setFromMinutes()
469
470 /**
471 * Set the time span from a total number of minutes.
472 *
473 * @param float $minutes Total number of minutes.
474 *
475 * @return bool True on success.
476 *
477 * @access public
478 */
479 function setFromMinutes($minutes)
480 {
481 return $this->setFromSeconds(round($minutes * 60));
482 }
483
484 // }}}
485 // {{{ setFromHours()
486
487 /**
488 * Set the time span from a total number of hours.
489 *
490 * @param float $hours Total number of hours.
491 *
492 * @return bool True on success.
493 *
494 * @access public
495 */
496 function setFromHours($hours)
497 {
498 return $this->setFromSeconds(round($hours * 3600));
499 }
500
501 // }}}
502 // {{{ setFromDays()
503
504 /**
505 * Set the time span from a total number of days.
506 *
507 * @param float $days Total number of days.
508 *
509 * @return bool True on success.
510 *
511 * @access public
512 */
513 function setFromDays($days)
514 {
515 return $this->setFromSeconds(round($days * 86400));
516 }
517
518 // }}}
519 // {{{ setFromDateDiff()
520
521 /**
522 * Set the span from the elapsed time between two dates.
523 *
524 * Set the span from the elapsed time between two dates. The time span
525 * is allways positive, so the date's order is not important.
526 *
527 * @param object Date $date1 First Date.
528 * @param object Date $date2 Second Date.
529 *
530 * @return bool True on success.
531 *
532 * @access public
533 */
534 function setFromDateDiff($date1, $date2)
535 {
536 if (!is_a($date1, 'date') or !is_a($date2, 'date')) {
537 return false;
538 }
539 $date1->toUTC();
540 $date2->toUTC();
541 if ($date1->after($date2)) {
542 list($date1, $date2) = array($date2, $date1);
543 }
544 $days = Date_Calc::dateDiff(
545 $date1->getDay(), $date1->getMonth(), $date1->getYear(),
546 $date2->getDay(), $date2->getMonth(), $date2->getYear()
547 );
548 $hours = $date2->getHour() - $date1->getHour();
549 $mins = $date2->getMinute() - $date1->getMinute();
550 $secs = $date2->getSecond() - $date1->getSecond();
551 $this->setFromSeconds(
552 $days * 86400 + $hours * 3600 + $mins * 60 + $secs
553 );
554 return true;
555 }
556
557 // }}}
558 // {{{ copy()
559
560 /**
561 * Set the time span from another time object.
562 *
563 * @param object Date_Span $time Source time span object.
564 *
565 * @return bool True on success.
566 *
567 * @access public
568 */
569 function copy($time)
570 {
571 if (is_a($time, 'date_span')) {
572 $this->second = $time->second;
573 $this->minute = $time->minute;
574 $this->hour = $time->hour;
575 $this->day = $time->day;
576 return true;
577 } else {
578 return false;
579 }
580 }
581
582 // }}}
583 // {{{ format()
584
585 /**
586 * Time span pretty printing (similar to Date::format()).
587 *
588 * Formats the time span in the given format, similar to
589 * strftime() and Date::format().<br>
590 * <br>
591 * Formatting options:<br>
592 * <code>%C</code> Days with time, same as "%D, %H:%M:%S".<br>
593 * <code>%d</code> Total days as a float number
594 * (2 days, 12 hours = 2.5 days).<br>
595 * <code>%D</code> Days as a decimal number.<br>
596 * <code>%e</code> Total hours as a float number
597 * (1 day, 2 hours, 30 minutes = 26.5 hours).<br>
598 * <code>%E</code> Total hours as a decimal number
599 * (1 day, 2 hours, 40 minutes = 26 hours).<br>
600 * <code>%f</code> Total minutes as a float number
601 * (2 minutes, 30 seconds = 2.5 minutes).<br>
602 * <code>%F</code> Total minutes as a decimal number
603 * (1 hour, 2 minutes, 40 seconds = 62 minutes).<br>
604 * <code>%g</code> Total seconds as a decimal number
605 * (2 minutes, 30 seconds = 90 seconds).<br>
606 * <code>%h</code> Hours as decimal number (0 to 23).<br>
607 * <code>%H</code> Hours as decimal number (00 to 23).<br>
608 * <code>%i</code> Hours as decimal number on 12-hour clock
609 * (1 to 12).<br>
610 * <code>%I</code> Hours as decimal number on 12-hour clock
611 * (01 to 12).<br>
612 * <code>%m</code> Minutes as a decimal number (0 to 59).<br>
613 * <code>%M</code> Minutes as a decimal number (00 to 59).<br>
614 * <code>%n</code> Newline character (\n).<br>
615 * <code>%p</code> Either 'am' or 'pm' depending on the time.<br>
616 * <code>%P</code> Either 'AM' or 'PM' depending on the time.<br>
617 * <code>%r</code> Time in am/pm notation, same as "%I:%M:%S %p".<br>
618 * <code>%R</code> Time in 24-hour notation, same as "%H:%M".<br>
619 * <code>%s</code> Seconds as a decimal number (0 to 59).<br>
620 * <code>%S</code> Seconds as a decimal number (00 to 59).<br>
621 * <code>%t</code> Tab character (\t).<br>
622 * <code>%T</code> Current time equivalent, same as "%H:%M:%S".<br>
623 * <code>%%</code> Literal '%'.<br>
624 *
625 * @param string $format The format string for returned time span.
626 *
627 * @return string The time span in specified format.
628 *
629 * @access public
630 */
631 function format($format = null)
632 {
633 if (is_null($format)) {
634 $format = $GLOBALS['_DATE_SPAN_FORMAT'];
635 }
636 $output = '';
637 for ($i = 0; $i < strlen($format); $i++) {
638 $char = $format{$i};
639 if ($char == '%') {
640 $nextchar = $format{++$i};
641 switch ($nextchar) {
642 case 'C':
643 $output .= sprintf(
644 '%d, %02d:%02d:%02d',
645 $this->day,
646 $this->hour,
647 $this->minute,
648 $this->second
649 );
650 break;
651 case 'd':
652 $output .= $this->toDays();
653 break;
654 case 'D':
655 $output .= $this->day;
656 break;
657 case 'e':
658 $output .= $this->toHours();
659 break;
660 case 'E':
661 $output .= floor($this->toHours());
662 break;
663 case 'f':
664 $output .= $this->toMinutes();
665 break;
666 case 'F':
667 $output .= floor($this->toMinutes());
668 break;
669 case 'g':
670 $output .= $this->toSeconds();
671 break;
672 case 'h':
673 $output .= $this->hour;
674 break;
675 case 'H':
676 $output .= sprintf('%02d', $this->hour);
677 break;
678 case 'i':
679 $hour =
680 ($this->hour + 1) > 12 ?
681 $this->hour - 12 :
682 $this->hour;
683 $output .= ($hour == 0) ? 12 : $hour;
684 break;
685 case 'I':
686 $hour =
687 ($this->hour + 1) > 12 ?
688 $this->hour - 12 :
689 $this->hour;
690 $output .= sprintf('%02d', $hour==0 ? 12 : $hour);
691 break;
692 case 'm':
693 $output .= $this->minute;
694 break;
695 case 'M':
696 $output .= sprintf('%02d',$this->minute);
697 break;
698 case 'n':
699 $output .= "\n";
700 break;
701 case 'p':
702 $output .= $this->hour >= 12 ? 'pm' : 'am';
703 break;
704 case 'P':
705 $output .= $this->hour >= 12 ? 'PM' : 'AM';
706 break;
707 case 'r':
708 $hour =
709 ($this->hour + 1) > 12 ?
710 $this->hour - 12 :
711 $this->hour;
712 $output .= sprintf(
713 '%02d:%02d:%02d %s',
714 $hour==0 ? 12 : $hour,
715 $this->minute,
716 $this->second,
717 $this->hour >= 12 ? 'pm' : 'am'
718 );
719 break;
720 case 'R':
721 $output .= sprintf(
722 '%02d:%02d', $this->hour, $this->minute
723 );
724 break;
725 case 's':
726 $output .= $this->second;
727 break;
728 case 'S':
729 $output .= sprintf('%02d', $this->second);
730 break;
731 case 't':
732 $output .= "\t";
733 break;
734 case 'T':
735 $output .= sprintf(
736 '%02d:%02d:%02d',
737 $this->hour, $this->minute, $this->second
738 );
739 break;
740 case '%':
741 $output .= "%";
742 break;
743 default:
744 $output .= $char . $nextchar;
745 }
746 } else {
747 $output .= $char;
748 }
749 }
750 return $output;
751 }
752
753 // }}}
754 // {{{ toSeconds()
755
756 /**
757 * Convert time span to seconds.
758 *
759 * @return int Time span as an integer number of seconds.
760 *
761 * @access public
762 */
763 function toSeconds()
764 {
765 return $this->day * 86400 + $this->hour * 3600 +
766 $this->minute * 60 + $this->second;
767 }
768
769 // }}}
770 // {{{ toMinutes()
771
772 /**
773 * Convert time span to minutes.
774 *
775 * @return float Time span as a decimal number of minutes.
776 *
777 * @access public
778 */
779 function toMinutes()
780 {
781 return $this->day * 1440 + $this->hour * 60 + $this->minute +
782 $this->second / 60;
783 }
784
785 // }}}
786 // {{{ toHours()
787
788 /**
789 * Convert time span to hours.
790 *
791 * @return float Time span as a decimal number of hours.
792 *
793 * @access public
794 */
795 function toHours()
796 {
797 return $this->day * 24 + $this->hour + $this->minute / 60 +
798 $this->second / 3600;
799 }
800
801 // }}}
802 // {{{ toDays()
803
804 /**
805 * Convert time span to days.
806 *
807 * @return float Time span as a decimal number of days.
808 *
809 * @access public
810 */
811 function toDays()
812 {
813 return $this->day + $this->hour / 24 + $this->minute / 1440 +
814 $this->second / 86400;
815 }
816
817 // }}}
818 // {{{ add()
819
820 /**
821 * Adds a time span.
822 *
823 * @param object Date_Span $time Time span to add.
824 *
825 * @access public
826 */
827 function add($time)
828 {
829 return $this->setFromSeconds(
830 $this->toSeconds() + $time->toSeconds()
831 );
832 }
833
834 // }}}
835 // {{{ substract()
836
837 /**
838 * Subtracts a time span.
839 *
840 * Subtracts a time span. If the time span to subtract is larger
841 * than the original, the result is zero (there's no sense in
842 * negative time spans).
843 *
844 * @param object Date_Span $time Time span to subtract.
845 *
846 * @access public
847 */
848 function subtract($time)
849 {
850 $sub = $this->toSeconds() - $time->toSeconds();
851 if ($sub < 0) {
852 $this->setFromSeconds(0);
853 } else {
854 $this->setFromSeconds($sub);
855 }
856 }
857
858 // }}}
859 // {{{ equal()
860
861 /**
862 * Tells if time span is equal to $time.
863 *
864 * @param object Date_Span $time Time span to compare to.
865 *
866 * @return bool True if the time spans are equal.
867 *
868 * @access public
869 */
870 function equal($time)
871 {
872 return $this->toSeconds() == $time->toSeconds();
873 }
874
875 // }}}
876 // {{{ greaterEqual()
877
878 /**
879 * Tells if this time span is greater or equal than $time.
880 *
881 * @param object Date_Span $time Time span to compare to.
882 *
883 * @return bool True if this time span is greater or equal than $time.
884 *
885 * @access public
886 */
887 function greaterEqual($time)
888 {
889 return $this->toSeconds() >= $time->toSeconds();
890 }
891
892 // }}}
893 // {{{ lowerEqual()
894
895 /**
896 * Tells if this time span is lower or equal than $time.
897 *
898 * @param object Date_Span $time Time span to compare to.
899 *
900 * @return bool True if this time span is lower or equal than $time.
901 *
902 * @access public
903 */
904 function lowerEqual($time)
905 {
906 return $this->toSeconds() <= $time->toSeconds();
907 }
908
909 // }}}
910 // {{{ greater()
911
912 /**
913 * Tells if this time span is greater than $time.
914 *
915 * @param object Date_Span $time Time span to compare to.
916 *
917 * @return bool True if this time span is greater than $time.
918 *
919 * @access public
920 */
921 function greater($time)
922 {
923 return $this->toSeconds() > $time->toSeconds();
924 }
925
926 // }}}
927 // {{{ lower()
928
929 /**
930 * Tells if this time span is lower than $time.
931 *
932 * @param object Date_Span $time Time span to compare to.
933 *
934 * @return bool True if this time span is lower than $time.
935 *
936 * @access public
937 */
938 function lower($time)
939 {
940 return $this->toSeconds() < $time->toSeconds();
941 }
942
943 // }}}
944 // {{{ compare()
945
946 /**
947 * Compares two time spans.
948 *
949 * Compares two time spans. Suitable for use in sorting functions.
950 *
951 * @param object Date_Span $time1 The first time span.
952 * @param object Date_Span $time2 The second time span.
953 *
954 * @return int 0 if the time spans are equal, -1 if time1 is lower
955 * than time2, 1 if time1 is greater than time2.
956 *
957 * @static
958 * @access public
959 */
960 function compare($time1, $time2)
961 {
962 if ($time1->equal($time2)) {
963 return 0;
964 } elseif ($time1->lower($time2)) {
965 return -1;
966 } else {
967 return 1;
968 }
969 }
970
971 // }}}
972 // {{{ isEmpty()
973
974 /**
975 * Tells if the time span is empty (zero length).
976 *
977 * @return bool True is it's empty.
978 */
979 function isEmpty()
980 {
981 return !$this->day && !$this->hour && !$this->minute && !$this->second;
982 }
983
984 // }}}
985 // {{{ setDefaultInputFormat()
986
987 /**
988 * Set the default input format.
989 *
990 * @param mixed $format New default input format.
991 *
992 * @return mixed Previous default input format.
993 *
994 * @static
995 */
996 function setDefaultInputFormat($format)
997 {
998 $old = $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
999 $GLOBALS['_DATE_SPAN_INPUT_FORMAT'] = $format;
1000 return $old;
1001 }
1002
1003 // }}}
1004 // {{{ getDefaultInputFormat()
1005
1006 /**
1007 * Get the default input format.
1008 *
1009 * @return mixed Default input format.
1010 *
1011 * @static
1012 */
1013 function getDefaultInputFormat()
1014 {
1015 return $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
1016 }
1017
1018 // }}}
1019 // {{{ setDefaultFormat()
1020
1021 /**
1022 * Set the default format.
1023 *
1024 * @param mixed $format New default format.
1025 *
1026 * @return mixed Previous default format.
1027 *
1028 * @static
1029 */
1030 function setDefaultFormat($format)
1031 {
1032 $old = $GLOBALS['_DATE_SPAN_FORMAT'];
1033 $GLOBALS['_DATE_SPAN_FORMAT'] = $format;
1034 return $old;
1035 }
1036
1037 // }}}
1038 // {{{ getDefaultFormat()
1039
1040 /**
1041 * Get the default format.
1042 *
1043 * @return mixed Default format.
1044 *
1045 * @static
1046 */
1047 function getDefaultFormat()
1048 {
1049 return $GLOBALS['_DATE_SPAN_FORMAT'];
1050 }
1051
1052 // }}}
1053 // {{{ __clone()
1054
1055 /**
1056 * Returns a copy of the object (workarround for PHP5 forward compatibility).
1057 *
1058 * @return object Date_Span Copy of the object.
1059 */
1060 function __clone() {
1061 $c = get_class($this);
1062 $s = new $c;
1063 $s->day = $this->day;
1064 $s->hour = $this->hour;
1065 $s->minute = $this->minute;
1066 $s->second = $this->second;
1067 return $s;
1068 }
1069
1070 // }}}
1071 }
1072
1073 // }}}
1074
1075 /*
1076 * Local variables:
1077 * mode: php
1078 * tab-width: 4
1079 * c-basic-offset: 4
1080 * c-hanging-comment-ender-p: nil
1081 * End:
1082 */
1083 ?>