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