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 }