]> git.mxchange.org Git - friendica-addons.git/blob - dav/sabre-vobject/lib/Sabre/VObject/Property/DateTime.php
Second part of refactoring; should be runnable again, yet not thoroughly tested
[friendica-addons.git] / dav / sabre-vobject / lib / Sabre / VObject / Property / DateTime.php
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-2012 Rooftop Solutions. All rights reserved.
21  * @author Evert Pot (http://www.rooftopsolutions.nl/)
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      * Parses the internal data structure to figure out what the current date
149      * and time is.
150      *
151      * The returned array contains two elements:
152      *   1. A 'DateType' constant (as defined on this class), or null.
153      *   2. A DateTime object (or null)
154      *
155      * @param string|null $propertyValue The string to parse (yymmdd or
156      *                                   ymmddThhmmss, etc..)
157      * @param \Sabre\VObject\Property|null $property The instance of the
158      *                                              property we're parsing.
159      * @return array
160      */
161     static public function parseData($propertyValue, VObject\Property $property = null) {
162
163         if (is_null($propertyValue)) {
164             return array(null, null);
165         }
166
167         $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
168         $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
169         $regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
170
171         if (!preg_match($regex, $propertyValue, $matches)) {
172             throw new \InvalidArgumentException($propertyValue . ' is not a valid \DateTime or Date string');
173         }
174
175         if (!isset($matches['hour'])) {
176             // Date-only
177             return array(
178                 self::DATE,
179                 new \DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00', new \DateTimeZone('UTC')),
180             );
181         }
182
183         $dateStr =
184             $matches['year'] .'-' .
185             $matches['month'] . '-' .
186             $matches['date'] . ' ' .
187             $matches['hour'] . ':' .
188             $matches['minute'] . ':' .
189             $matches['second'];
190
191         if (isset($matches['isutc'])) {
192             $dt = new \DateTime($dateStr,new \DateTimeZone('UTC'));
193             $dt->setTimeZone(new \DateTimeZone('UTC'));
194             return array(
195                 self::UTC,
196                 $dt
197             );
198         }
199
200         // Finding the timezone.
201         $tzid = $property['TZID'];
202         if (!$tzid) {
203             // This was a floating time string. This implies we use the
204             // timezone from date_default_timezone_set / date.timezone ini
205             // setting.
206             return array(
207                 self::LOCAL,
208                 new \DateTime($dateStr)
209             );
210         }
211
212         // To look up the timezone, we must first find the VCALENDAR component.
213         $root = $property;
214         while($root->parent) {
215             $root = $root->parent;
216         }
217         if ($root->name === 'VCALENDAR') {
218             $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root);
219         } else {
220             $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid);
221         }
222
223         $dt = new \DateTime($dateStr, $tz);
224         $dt->setTimeZone($tz);
225
226         return array(
227             self::LOCALTZ,
228             $dt
229         );
230
231     }
232
233 }