Mercurial > hg > rc1
comparison plugins/libcalendaring/lib/Sabre/VObject/Property/DateTime.php @ 4:888e774ee983
libcalendar plugin as distributed
| author | Charlie Root |
|---|---|
| date | Sat, 13 Jan 2018 08:57:56 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 3:f6fe4b6ae66a | 4:888e774ee983 |
|---|---|
| 1 <?php | |
| 2 | |
| 3 namespace Sabre\VObject\Property; | |
| 4 | |
| 5 use Sabre\VObject; | |
| 6 | |
| 7 /** | |
| 8 * DateTime property | |
| 9 * | |
| 10 * This element is used for iCalendar properties such as the DTSTART property. | |
| 11 * It basically provides a few helper functions that make it easier to deal | |
| 12 * with these. It supports both DATE-TIME and DATE values. | |
| 13 * | |
| 14 * In order to use this correctly, you must call setDateTime and getDateTime to | |
| 15 * retrieve and modify dates respectively. | |
| 16 * | |
| 17 * If you use the 'value' or properties directly, this object does not keep | |
| 18 * reference and results might appear incorrectly. | |
| 19 * | |
| 20 * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/). | |
| 21 * @author Evert Pot (http://evertpot.com/) | |
| 22 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License | |
| 23 */ | |
| 24 class DateTime extends VObject\Property { | |
| 25 | |
| 26 /** | |
| 27 * Local 'floating' time | |
| 28 */ | |
| 29 const LOCAL = 1; | |
| 30 | |
| 31 /** | |
| 32 * UTC-based time | |
| 33 */ | |
| 34 const UTC = 2; | |
| 35 | |
| 36 /** | |
| 37 * Local time plus timezone | |
| 38 */ | |
| 39 const LOCALTZ = 3; | |
| 40 | |
| 41 /** | |
| 42 * Only a date, time is ignored | |
| 43 */ | |
| 44 const DATE = 4; | |
| 45 | |
| 46 /** | |
| 47 * DateTime representation | |
| 48 * | |
| 49 * @var \DateTime | |
| 50 */ | |
| 51 protected $dateTime; | |
| 52 | |
| 53 /** | |
| 54 * dateType | |
| 55 * | |
| 56 * @var int | |
| 57 */ | |
| 58 protected $dateType; | |
| 59 | |
| 60 /** | |
| 61 * Updates the Date and Time. | |
| 62 * | |
| 63 * @param \DateTime $dt | |
| 64 * @param int $dateType | |
| 65 * @return void | |
| 66 */ | |
| 67 public function setDateTime(\DateTime $dt, $dateType = self::LOCALTZ) { | |
| 68 | |
| 69 switch($dateType) { | |
| 70 | |
| 71 case self::LOCAL : | |
| 72 $this->setValue($dt->format('Ymd\\THis')); | |
| 73 $this->offsetUnset('VALUE'); | |
| 74 $this->offsetUnset('TZID'); | |
| 75 $this->offsetSet('VALUE','DATE-TIME'); | |
| 76 break; | |
| 77 case self::UTC : | |
| 78 $dt->setTimeZone(new \DateTimeZone('UTC')); | |
| 79 $this->setValue($dt->format('Ymd\\THis\\Z')); | |
| 80 $this->offsetUnset('VALUE'); | |
| 81 $this->offsetUnset('TZID'); | |
| 82 $this->offsetSet('VALUE','DATE-TIME'); | |
| 83 break; | |
| 84 case self::LOCALTZ : | |
| 85 $this->setValue($dt->format('Ymd\\THis')); | |
| 86 $this->offsetUnset('VALUE'); | |
| 87 $this->offsetUnset('TZID'); | |
| 88 $this->offsetSet('VALUE','DATE-TIME'); | |
| 89 $this->offsetSet('TZID', $dt->getTimeZone()->getName()); | |
| 90 break; | |
| 91 case self::DATE : | |
| 92 $this->setValue($dt->format('Ymd')); | |
| 93 $this->offsetUnset('VALUE'); | |
| 94 $this->offsetUnset('TZID'); | |
| 95 $this->offsetSet('VALUE','DATE'); | |
| 96 break; | |
| 97 default : | |
| 98 throw new \InvalidArgumentException('You must pass a valid dateType constant'); | |
| 99 | |
| 100 } | |
| 101 $this->dateTime = $dt; | |
| 102 $this->dateType = $dateType; | |
| 103 | |
| 104 } | |
| 105 | |
| 106 /** | |
| 107 * Returns the current DateTime value. | |
| 108 * | |
| 109 * If no value was set, this method returns null. | |
| 110 * | |
| 111 * @return \DateTime|null | |
| 112 */ | |
| 113 public function getDateTime() { | |
| 114 | |
| 115 if ($this->dateTime) | |
| 116 return $this->dateTime; | |
| 117 | |
| 118 list( | |
| 119 $this->dateType, | |
| 120 $this->dateTime | |
| 121 ) = self::parseData($this->value, $this); | |
| 122 return $this->dateTime; | |
| 123 | |
| 124 } | |
| 125 | |
| 126 /** | |
| 127 * Returns the type of Date format. | |
| 128 * | |
| 129 * This method returns one of the format constants. If no date was set, | |
| 130 * this method will return null. | |
| 131 * | |
| 132 * @return int|null | |
| 133 */ | |
| 134 public function getDateType() { | |
| 135 | |
| 136 if ($this->dateType) | |
| 137 return $this->dateType; | |
| 138 | |
| 139 list( | |
| 140 $this->dateType, | |
| 141 $this->dateTime, | |
| 142 ) = self::parseData($this->value, $this); | |
| 143 return $this->dateType; | |
| 144 | |
| 145 } | |
| 146 | |
| 147 /** | |
| 148 * This method will return true, if the property had a date and a time, as | |
| 149 * opposed to only a date. | |
| 150 * | |
| 151 * @return bool | |
| 152 */ | |
| 153 public function hasTime() { | |
| 154 | |
| 155 return $this->getDateType()!==self::DATE; | |
| 156 | |
| 157 } | |
| 158 | |
| 159 /** | |
| 160 * Parses the internal data structure to figure out what the current date | |
| 161 * and time is. | |
| 162 * | |
| 163 * The returned array contains two elements: | |
| 164 * 1. A 'DateType' constant (as defined on this class), or null. | |
| 165 * 2. A DateTime object (or null) | |
| 166 * | |
| 167 * @param string|null $propertyValue The string to parse (yymmdd or | |
| 168 * ymmddThhmmss, etc..) | |
| 169 * @param \Sabre\VObject\Property|null $property The instance of the | |
| 170 * property we're parsing. | |
| 171 * @return array | |
| 172 */ | |
| 173 static public function parseData($propertyValue, VObject\Property $property = null) { | |
| 174 | |
| 175 if (is_null($propertyValue)) { | |
| 176 return array(null, null); | |
| 177 } | |
| 178 | |
| 179 $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])'; | |
| 180 $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])'; | |
| 181 $regex = "/^$date(T$time(?P<isutc>Z)?)?$/"; | |
| 182 | |
| 183 if (!preg_match($regex, $propertyValue, $matches)) { | |
| 184 throw new \InvalidArgumentException($propertyValue . ' is not a valid \DateTime or Date string'); | |
| 185 } | |
| 186 | |
| 187 if (!isset($matches['hour'])) { | |
| 188 // Date-only | |
| 189 return array( | |
| 190 self::DATE, | |
| 191 new \DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00', new \DateTimeZone('UTC')), | |
| 192 ); | |
| 193 } | |
| 194 | |
| 195 $dateStr = | |
| 196 $matches['year'] .'-' . | |
| 197 $matches['month'] . '-' . | |
| 198 $matches['date'] . ' ' . | |
| 199 $matches['hour'] . ':' . | |
| 200 $matches['minute'] . ':' . | |
| 201 $matches['second']; | |
| 202 | |
| 203 if (isset($matches['isutc'])) { | |
| 204 $dt = new \DateTime($dateStr,new \DateTimeZone('UTC')); | |
| 205 $dt->setTimeZone(new \DateTimeZone('UTC')); | |
| 206 return array( | |
| 207 self::UTC, | |
| 208 $dt | |
| 209 ); | |
| 210 } | |
| 211 | |
| 212 // Finding the timezone. | |
| 213 $tzid = $property['TZID']; | |
| 214 if (!$tzid) { | |
| 215 // This was a floating time string. This implies we use the | |
| 216 // timezone from date_default_timezone_set / date.timezone ini | |
| 217 // setting. | |
| 218 return array( | |
| 219 self::LOCAL, | |
| 220 new \DateTime($dateStr) | |
| 221 ); | |
| 222 } | |
| 223 | |
| 224 // To look up the timezone, we must first find the VCALENDAR component. | |
| 225 $root = $property; | |
| 226 while($root->parent) { | |
| 227 $root = $root->parent; | |
| 228 } | |
| 229 if ($root->name === 'VCALENDAR') { | |
| 230 $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root); | |
| 231 } else { | |
| 232 $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid); | |
| 233 } | |
| 234 | |
| 235 $dt = new \DateTime($dateStr, $tz); | |
| 236 $dt->setTimeZone($tz); | |
| 237 | |
| 238 return array( | |
| 239 self::LOCALTZ, | |
| 240 $dt | |
| 241 ); | |
| 242 | |
| 243 } | |
| 244 | |
| 245 } |
