1<?php
2
3namespace Sabre\VObject;
4
5use DateTime;
6use DateTimeZone;
7use DateInterval;
8
9class DateTimeParserTest extends \PHPUnit_Framework_TestCase {
10
11    function testParseICalendarDuration() {
12
13        $this->assertEquals('+1 weeks', DateTimeParser::parseDuration('P1W',true));
14        $this->assertEquals('+5 days',  DateTimeParser::parseDuration('P5D',true));
15        $this->assertEquals('+5 days 3 hours 50 minutes 12 seconds', DateTimeParser::parseDuration('P5DT3H50M12S',true));
16        $this->assertEquals('-1 weeks 50 minutes', DateTimeParser::parseDuration('-P1WT50M',true));
17        $this->assertEquals('+50 days 3 hours 2 seconds', DateTimeParser::parseDuration('+P50DT3H2S',true));
18        $this->assertEquals('+0 seconds', DateTimeParser::parseDuration('+PT0S',true));
19        $this->assertEquals(new DateInterval('PT0S'), DateTimeParser::parseDuration('PT0S'));
20
21    }
22
23    function testParseICalendarDurationDateInterval() {
24
25        $expected = new DateInterval('P7D');
26        $this->assertEquals($expected, DateTimeParser::parseDuration('P1W'));
27        $this->assertEquals($expected, DateTimeParser::parse('P1W'));
28
29        $expected = new DateInterval('PT3M');
30        $expected->invert = true;
31        $this->assertEquals($expected, DateTimeParser::parseDuration('-PT3M'));
32
33    }
34
35    /**
36     * @expectedException LogicException
37     */
38    function testParseICalendarDurationFail() {
39
40        DateTimeParser::parseDuration('P1X',true);
41
42    }
43
44    function testParseICalendarDateTime() {
45
46        $dateTime = DateTimeParser::parseDateTime('20100316T141405');
47
48        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
49
50        $this->assertEquals($compare, $dateTime);
51
52    }
53
54    /**
55     * @depends testParseICalendarDateTime
56     * @expectedException LogicException
57     */
58    function testParseICalendarDateTimeBadFormat() {
59
60        $dateTime = DateTimeParser::parseDateTime('20100316T141405 ');
61
62    }
63
64    /**
65     * @depends testParseICalendarDateTime
66     */
67    function testParseICalendarDateTimeUTC() {
68
69        $dateTime = DateTimeParser::parseDateTime('20100316T141405Z');
70
71        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
72        $this->assertEquals($compare, $dateTime);
73
74    }
75
76    /**
77     * @depends testParseICalendarDateTime
78     */
79    function testParseICalendarDateTimeUTC2() {
80
81        $dateTime = DateTimeParser::parseDateTime('20101211T160000Z');
82
83        $compare = new DateTime('2010-12-11 16:00:00',new DateTimeZone('UTC'));
84        $this->assertEquals($compare, $dateTime);
85
86    }
87
88    /**
89     * @depends testParseICalendarDateTime
90     */
91    function testParseICalendarDateTimeCustomTimeZone() {
92
93        $dateTime = DateTimeParser::parseDateTime('20100316T141405', new DateTimeZone('Europe/Amsterdam'));
94
95        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('Europe/Amsterdam'));
96        $this->assertEquals($compare, $dateTime);
97
98    }
99
100    function testParseICalendarDate() {
101
102        $dateTime = DateTimeParser::parseDate('20100316');
103
104        $expected = new DateTime('2010-03-16 00:00:00',new DateTimeZone('UTC'));
105
106        $this->assertEquals($expected, $dateTime);
107
108        $dateTime = DateTimeParser::parse('20100316');
109        $this->assertEquals($expected, $dateTime);
110
111    }
112
113    /**
114     * TCheck if a date with year > 4000 will not throw an exception. iOS seems to use 45001231 in yearly recurring events
115     */
116    function testParseICalendarDateGreaterThan4000() {
117
118        $dateTime = DateTimeParser::parseDate('45001231');
119
120        $expected = new DateTime('4500-12-31 00:00:00',new DateTimeZone('UTC'));
121
122        $this->assertEquals($expected, $dateTime);
123
124        $dateTime = DateTimeParser::parse('45001231');
125        $this->assertEquals($expected, $dateTime);
126
127    }
128
129    /**
130     * Check if a datetime with year > 4000 will not throw an exception. iOS seems to use 45001231T235959 in yearly recurring events
131     */
132    function testParseICalendarDateTimeGreaterThan4000() {
133
134        $dateTime = DateTimeParser::parseDateTime('45001231T235959');
135
136        $expected = new DateTime('4500-12-31 23:59:59',new DateTimeZone('UTC'));
137
138        $this->assertEquals($expected, $dateTime);
139
140        $dateTime = DateTimeParser::parse('45001231T235959');
141        $this->assertEquals($expected, $dateTime);
142
143    }
144
145    /**
146     * @depends testParseICalendarDate
147     * @expectedException LogicException
148     */
149    function testParseICalendarDateBadFormat() {
150
151        $dateTime = DateTimeParser::parseDate('20100316T141405');
152
153    }
154
155    /**
156     * @dataProvider vcardDates
157     */
158    function testVCardDate($input, $output) {
159
160        $this->assertEquals(
161            $output,
162            DateTimeParser::parseVCardDateTime($input)
163        );
164
165    }
166
167    /**
168     * @dataProvider vcardDates
169     * @expectedException \InvalidArgumentException
170     */
171    function testBadVCardDate() {
172
173        DateTimeParser::parseVCardDateTime('1985---01');
174
175    }
176
177    /**
178     * @dataProvider vcardDates
179     * @expectedException \InvalidArgumentException
180     */
181    function testBadVCardTime() {
182
183        DateTimeParser::parseVCardTime('23:12:166');
184
185    }
186
187    function vcardDates() {
188
189        return array(
190            array(
191                "19961022T140000",
192                array(
193                    "year" => 1996,
194                    "month" => 10,
195                    "date" => 22,
196                    "hour" => 14,
197                    "minute" => 00,
198                    "second" => 00,
199                    "timezone" => null
200                ),
201            ),
202            array(
203                "--1022T1400",
204                array(
205                    "year" => null,
206                    "month" => 10,
207                    "date" => 22,
208                    "hour" => 14,
209                    "minute" => 00,
210                    "second" => null,
211                    "timezone" => null
212                ),
213            ),
214            array(
215                "---22T14",
216                array(
217                    "year" => null,
218                    "month" => null,
219                    "date" => 22,
220                    "hour" => 14,
221                    "minute" => null,
222                    "second" => null,
223                    "timezone" => null
224                ),
225            ),
226            array(
227                "19850412",
228                array(
229                    "year" => 1985,
230                    "month" => 4,
231                    "date" => 12,
232                    "hour" => null,
233                    "minute" => null,
234                    "second" => null,
235                    "timezone" => null
236                ),
237            ),
238            array(
239                "1985-04",
240                array(
241                    "year" => 1985,
242                    "month" => 04,
243                    "date" => null,
244                    "hour" => null,
245                    "minute" => null,
246                    "second" => null,
247                    "timezone" => null
248                ),
249            ),
250            array(
251                "1985",
252                array(
253                    "year" => 1985,
254                    "month" => null,
255                    "date" => null,
256                    "hour" => null,
257                    "minute" => null,
258                    "second" => null,
259                    "timezone" => null
260                ),
261            ),
262            array(
263                "--0412",
264                array(
265                    "year" => null,
266                    "month" => 4,
267                    "date" => 12,
268                    "hour" => null,
269                    "minute" => null,
270                    "second" => null,
271                    "timezone" => null
272                ),
273            ),
274            array(
275                "---12",
276                array(
277                    "year" => null,
278                    "month" => null,
279                    "date" => 12,
280                    "hour" => null,
281                    "minute" => null,
282                    "second" => null,
283                    "timezone" => null
284                ),
285            ),
286            array(
287                "T102200",
288                array(
289                    "year" => null,
290                    "month" => null,
291                    "date" => null,
292                    "hour" => 10,
293                    "minute" => 22,
294                    "second" => 0,
295                    "timezone" => null
296                ),
297            ),
298            array(
299                "T1022",
300                array(
301                    "year" => null,
302                    "month" => null,
303                    "date" => null,
304                    "hour" => 10,
305                    "minute" => 22,
306                    "second" => null,
307                    "timezone" => null
308                ),
309            ),
310            array(
311                "T10",
312                array(
313                    "year" => null,
314                    "month" => null,
315                    "date" => null,
316                    "hour" => 10,
317                    "minute" => null,
318                    "second" => null,
319                    "timezone" => null
320                ),
321            ),
322            array(
323                "T-2200",
324                array(
325                    "year" => null,
326                    "month" => null,
327                    "date" => null,
328                    "hour" => null,
329                    "minute" => 22,
330                    "second" => 00,
331                    "timezone" => null
332                ),
333            ),
334            array(
335                "T--00",
336                array(
337                    "year" => null,
338                    "month" => null,
339                    "date" => null,
340                    "hour" => null,
341                    "minute" => null,
342                    "second" => 00,
343                    "timezone" => null
344                ),
345            ),
346            array(
347                "T102200Z",
348                array(
349                    "year" => null,
350                    "month" => null,
351                    "date" => null,
352                    "hour" => 10,
353                    "minute" => 22,
354                    "second" => 00,
355                    "timezone" => 'Z'
356                ),
357            ),
358            array(
359                "T102200-0800",
360                array(
361                    "year" => null,
362                    "month" => null,
363                    "date" => null,
364                    "hour" => 10,
365                    "minute" => 22,
366                    "second" => 00,
367                    "timezone" => '-0800'
368                ),
369            ),
370
371            // extended format
372            array(
373                "2012-11-29T15:10:53Z",
374                array(
375                    "year" => 2012,
376                    "month" => 11,
377                    "date" => 29,
378                    "hour" => 15,
379                    "minute" => 10,
380                    "second" => 53,
381                    "timezone" => 'Z'
382                ),
383            ),
384
385            // with milliseconds
386            array(
387                "20121129T151053.123Z",
388                array(
389                    "year" => 2012,
390                    "month" => 11,
391                    "date" => 29,
392                    "hour" => 15,
393                    "minute" => 10,
394                    "second" => 53,
395                    "timezone" => 'Z'
396                ),
397            ),
398
399            // extended format with milliseconds
400            array(
401                "2012-11-29T15:10:53.123Z",
402                array(
403                    "year" => 2012,
404                    "month" => 11,
405                    "date" => 29,
406                    "hour" => 15,
407                    "minute" => 10,
408                    "second" => 53,
409                    "timezone" => 'Z'
410                ),
411            ),
412
413        );
414
415    }
416
417}
418