1<?php 2/** 3 * Copyright 2009-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file COPYING for license information (LGPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 7 * 8 * @author Chuck Hagenbuch <chuck@horde.org> 9 * @category Horde 10 * @license http://www.horde.org/licenses/lgpl21 LGPL 11 * @package Date 12 */ 13 14/** 15 * Date repeater. 16 * 17 * @author Chuck Hagenbuch <chuck@horde.org> 18 * @category Horde 19 * @copyright 2009-2017 Horde LLC 20 * @license http://www.horde.org/licenses/lgpl21 LGPL 21 * @package Date 22 */ 23class Horde_Date_Repeater_Time extends Horde_Date_Repeater 24{ 25 public $currentTime; 26 public $type; 27 public $ambiguous; 28 29 public function __construct($time) 30 { 31 $t = str_replace(':', '', $time); 32 33 switch (strlen($t)) { 34 case 1: 35 case 2: 36 $hours = (int)$t; 37 $this->ambiguous = true; 38 $this->type = ($hours == 12) ? 0 : $hours * 3600; 39 break; 40 41 case 3: 42 $this->ambiguous = true; 43 $this->type = $t[0] * 3600 + (int)substr($t, 1, 2) * 60; 44 break; 45 46 case 4: 47 $this->ambiguous = (strpos($time, ':') !== false) && ($t[0] != 0) && ((int)substr($t, 0, 2) <= 12); 48 $hours = (int)substr($t, 0, 2); 49 $this->type = ($hours == 12) ? 50 ((int)substr($t, 2, 2) * 60) : 51 ($hours * 60 * 60 + (int)substr($t, 2, 2) * 60); 52 break; 53 54 case 5: 55 $this->ambiguous = true; 56 $this->type = $t[0] * 3600 + (int)substr($t, 1, 2) * 60 + (int)substr($t, 3, 2); 57 break; 58 59 case 6: 60 $this->ambiguous = (strpos($time, ':') !== false) && ($t[0] != 0) && ((int)substr($t, 0, 2) <= 12); 61 $hours = (int)substr($t, 0, 2); 62 $this->type = ($hours == 12) ? 63 ((int)substr($t, 2, 2) * 60 + (int)substr($t, 4, 2)) : 64 ($hours * 60 * 60 + (int)substr($t, 2, 2) * 60 + (int)substr($t, 4, 2)); 65 break; 66 67 default: 68 throw new Horde_Date_Repeater_Exception('Time cannot exceed six digits'); 69 } 70 } 71 72 /** 73 * Return the next past or future Span for the time that this Repeater represents 74 * pointer - Symbol representing which temporal direction to fetch the next day 75 * must be either :past or :future 76 */ 77 public function next($pointer = 'future') 78 { 79 parent::next($pointer); 80 81 $halfDay = 3600 * 12; 82 $fullDay = 3600 * 24; 83 84 $first = false; 85 86 if (!$this->currentTime) { 87 $first = true; 88 $midnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day)); 89 $yesterdayMidnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day - 1)); 90 $tomorrowMidnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day + 1)); 91 92 if ($pointer == 'future') { 93 if ($this->ambiguous) { 94 foreach (array($midnight->add($this->type), $midnight->add($halfDay + $this->type), $tomorrowMidnight->add($this->type)) as $t) { 95 if ($t->compareDateTime($this->now) >= 0) { 96 $this->currentTime = $t; 97 break; 98 } 99 } 100 } else { 101 foreach (array($midnight->add($this->type), $tomorrowMidnight->add($this->type)) as $t) { 102 if ($t->compareDateTime($this->now) >= 0) { 103 $this->currentTime = $t; 104 break; 105 } 106 } 107 } 108 } elseif ($pointer == 'past') { 109 if ($this->ambiguous) { 110 foreach (array($midnight->add($halfDay + $this->type), $midnight->add($this->type), $yesterdayMidnight->add($this->type * 2)) as $t) { 111 if ($t->compareDateTime($this->now) <= 0) { 112 $this->currentTime = $t; 113 break; 114 } 115 } 116 } else { 117 foreach (array($midnight->add($this->type), $yesterdayMidnight->add($this->type)) as $t) { 118 if ($t->compareDateTime($this->now) <= 0) { 119 $this->currentTime = $t; 120 break; 121 } 122 } 123 } 124 } 125 126 if (!$this->currentTime) { 127 throw new Horde_Date_Repeater_Exception('Current time cannot be null at this point'); 128 } 129 } 130 131 if (!$first) { 132 $increment = $this->ambiguous ? $halfDay : $fullDay; 133 $this->currentTime->sec += ($pointer == 'future') ? $increment : -$increment; 134 } 135 136 return new Horde_Date_Span($this->currentTime, $this->currentTime->add(1)); 137 } 138 139 public function this($context = 'future') 140 { 141 parent::this($context); 142 143 if ($context == 'none') { 144 $context = 'future'; 145 } 146 return $this->next($context); 147 } 148 149 public function width() 150 { 151 return 1; 152 } 153 154 public function __toString() 155 { 156 return parent::__toString() . '-time-' . $this->type; 157 } 158 159} 160