1<?php
2
3namespace Sabre\VObject\Property\ICalendar;
4
5use Sabre\VObject\Component;
6use Sabre\VObject\Component\VCalendar;
7
8
9class DateTimeTest extends \PHPUnit_Framework_TestCase {
10
11    protected $vcal;
12
13    function setUp() {
14
15        $this->vcal = new VCalendar();
16
17    }
18
19    function testSetDateTime() {
20
21        $tz = new \DateTimeZone('Europe/Amsterdam');
22        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
23        $dt->setTimeZone($tz);
24
25        $elem = $this->vcal->createProperty('DTSTART');
26        $elem->setDateTime($dt);
27
28        $this->assertEquals('19850704T013000', (string)$elem);
29        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
30        $this->assertNull($elem['VALUE']);
31
32        $this->assertTrue($elem->hasTime());
33
34    }
35
36    function testSetDateTimeLOCAL() {
37
38        $tz = new \DateTimeZone('Europe/Amsterdam');
39        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
40        $dt->setTimeZone($tz);
41
42        $elem = $this->vcal->createProperty('DTSTART');
43        $elem->setDateTime($dt, $isFloating = true);
44
45        $this->assertEquals('19850704T013000', (string)$elem);
46        $this->assertNull($elem['TZID']);
47
48        $this->assertTrue($elem->hasTime());
49    }
50
51    function testSetDateTimeUTC() {
52
53        $tz = new \DateTimeZone('GMT');
54        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
55        $dt->setTimeZone($tz);
56
57        $elem = $this->vcal->createProperty('DTSTART');
58        $elem->setDateTime($dt);
59
60        $this->assertEquals('19850704T013000Z', (string)$elem);
61        $this->assertNull($elem['TZID']);
62
63        $this->assertTrue($elem->hasTime());
64    }
65
66    function testSetDateTimeLOCALTZ() {
67
68        $tz = new \DateTimeZone('Europe/Amsterdam');
69        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
70        $dt->setTimeZone($tz);
71
72        $elem = $this->vcal->createProperty('DTSTART');
73        $elem->setDateTime($dt);
74
75        $this->assertEquals('19850704T013000', (string)$elem);
76        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
77
78        $this->assertTrue($elem->hasTime());
79    }
80
81    function testSetDateTimeDATE() {
82
83        $tz = new \DateTimeZone('Europe/Amsterdam');
84        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
85        $dt->setTimeZone($tz);
86
87        $elem = $this->vcal->createProperty('DTSTART');
88        $elem['VALUE'] = 'DATE';
89        $elem->setDateTime($dt);
90
91        $this->assertEquals('19850704', (string)$elem);
92        $this->assertNull($elem['TZID']);
93        $this->assertEquals('DATE', (string)$elem['VALUE']);
94
95        $this->assertFalse($elem->hasTime());
96    }
97
98    function testSetValue() {
99
100        $tz = new \DateTimeZone('Europe/Amsterdam');
101        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
102        $dt->setTimeZone($tz);
103
104        $elem = $this->vcal->createProperty('DTSTART');
105        $elem->setValue($dt);
106
107        $this->assertEquals('19850704T013000', (string)$elem);
108        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
109        $this->assertNull($elem['VALUE']);
110
111        $this->assertTrue($elem->hasTime());
112
113    }
114
115    function testSetValueArray() {
116
117        $tz = new \DateTimeZone('Europe/Amsterdam');
118        $dt1 = new \DateTime('1985-07-04 01:30:00', $tz);
119        $dt2 = new \DateTime('1985-07-04 02:30:00', $tz);
120        $dt1->setTimeZone($tz);
121        $dt2->setTimeZone($tz);
122
123        $elem = $this->vcal->createProperty('DTSTART');
124        $elem->setValue(array($dt1, $dt2));
125
126        $this->assertEquals('19850704T013000,19850704T023000', (string)$elem);
127        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
128        $this->assertNull($elem['VALUE']);
129
130        $this->assertTrue($elem->hasTime());
131
132    }
133
134    function testSetParts() {
135
136        $tz = new \DateTimeZone('Europe/Amsterdam');
137        $dt1 = new \DateTime('1985-07-04 01:30:00', $tz);
138        $dt2 = new \DateTime('1985-07-04 02:30:00', $tz);
139        $dt1->setTimeZone($tz);
140        $dt2->setTimeZone($tz);
141
142        $elem = $this->vcal->createProperty('DTSTART');
143        $elem->setParts(array($dt1, $dt2));
144
145        $this->assertEquals('19850704T013000,19850704T023000', (string)$elem);
146        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
147        $this->assertNull($elem['VALUE']);
148
149        $this->assertTrue($elem->hasTime());
150
151    }
152    function testSetPartsStrings() {
153
154        $dt1 = '19850704T013000Z';
155        $dt2 = '19850704T023000Z';
156
157        $elem = $this->vcal->createProperty('DTSTART');
158        $elem->setParts(array($dt1, $dt2));
159
160        $this->assertEquals('19850704T013000Z,19850704T023000Z', (string)$elem);
161        $this->assertNull($elem['VALUE']);
162
163        $this->assertTrue($elem->hasTime());
164
165    }
166
167
168    function testGetDateTimeCached() {
169
170        $tz = new \DateTimeZone('Europe/Amsterdam');
171        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
172        $dt->setTimeZone($tz);
173
174        $elem = $this->vcal->createProperty('DTSTART');
175        $elem->setDateTime($dt);
176
177        $this->assertEquals($elem->getDateTime(), $dt);
178
179    }
180
181    function testGetDateTimeDateNULL() {
182
183        $elem = $this->vcal->createProperty('DTSTART');
184        $dt = $elem->getDateTime();
185
186        $this->assertNull($dt);
187
188    }
189
190    function testGetDateTimeDateDATE() {
191
192        $elem = $this->vcal->createProperty('DTSTART','19850704');
193        $dt = $elem->getDateTime();
194
195        $this->assertInstanceOf('DateTime', $dt);
196        $this->assertEquals('1985-07-04 00:00:00', $dt->format('Y-m-d H:i:s'));
197
198    }
199
200    function testGetDateTimeDateDATEReferenceTimeZone() {
201
202        $elem = $this->vcal->createProperty('DTSTART','19850704');
203
204        $tz = new \DateTimeZone('America/Toronto');
205        $dt = $elem->getDateTime($tz);
206        $dt->setTimeZone(new \DateTimeZone('UTC'));
207
208        $this->assertInstanceOf('DateTime', $dt);
209        $this->assertEquals('1985-07-04 04:00:00', $dt->format('Y-m-d H:i:s'));
210
211    }
212
213    function testGetDateTimeDateFloating() {
214
215        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
216        $dt = $elem->getDateTime();
217
218        $this->assertInstanceOf('DateTime', $dt);
219        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
220
221    }
222
223    function testGetDateTimeDateFloatingReferenceTimeZone() {
224
225        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
226
227        $tz = new \DateTimeZone('America/Toronto');
228        $dt = $elem->getDateTime($tz);
229        $dt->setTimeZone(new \DateTimeZone('UTC'));
230
231        $this->assertInstanceOf('DateTime', $dt);
232        $this->assertEquals('1985-07-04 05:30:00', $dt->format('Y-m-d H:i:s'));
233
234    }
235
236    function testGetDateTimeDateUTC() {
237
238        $elem = $this->vcal->createProperty('DTSTART','19850704T013000Z');
239        $dt = $elem->getDateTime();
240
241        $this->assertInstanceOf('DateTime', $dt);
242        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
243        $this->assertEquals('UTC', $dt->getTimeZone()->getName());
244
245    }
246
247    function testGetDateTimeDateLOCALTZ() {
248
249        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
250        $elem['TZID'] = 'Europe/Amsterdam';
251
252        $dt = $elem->getDateTime();
253
254        $this->assertInstanceOf('DateTime', $dt);
255        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
256        $this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
257
258    }
259
260    /**
261     * @expectedException LogicException
262     */
263    function testGetDateTimeDateInvalid() {
264
265        $elem = $this->vcal->createProperty('DTSTART','bla');
266        $dt = $elem->getDateTime();
267
268    }
269
270    function testGetDateTimeWeirdTZ() {
271
272        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
273        $elem['TZID'] = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
274
275
276        $event = $this->vcal->createComponent('VEVENT');
277        $event->add($elem);
278
279        $timezone = $this->vcal->createComponent('VTIMEZONE');
280        $timezone->TZID = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
281        $timezone->{'X-LIC-LOCATION'} = 'Europe/Amsterdam';
282
283        $this->vcal->add($event);
284        $this->vcal->add($timezone);
285
286        $dt = $elem->getDateTime();
287
288        $this->assertInstanceOf('DateTime', $dt);
289        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
290        $this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
291
292    }
293
294    function testGetDateTimeBadTimeZone() {
295
296        $default = date_default_timezone_get();
297        date_default_timezone_set('Canada/Eastern');
298
299        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
300        $elem['TZID'] = 'Moon';
301
302
303        $event = $this->vcal->createComponent('VEVENT');
304        $event->add($elem);
305
306        $timezone = $this->vcal->createComponent('VTIMEZONE');
307        $timezone->TZID = 'Moon';
308        $timezone->{'X-LIC-LOCATION'} = 'Moon';
309
310
311        $this->vcal->add($event);
312        $this->vcal->add($timezone);
313
314        $dt = $elem->getDateTime();
315
316        $this->assertInstanceOf('DateTime', $dt);
317        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
318        $this->assertEquals('Canada/Eastern', $dt->getTimeZone()->getName());
319        date_default_timezone_set($default);
320
321    }
322
323    function testUpdateValueParameter() {
324
325        $dtStart = $this->vcal->createProperty('DTSTART', new \DateTime('2013-06-07 15:05:00'));
326        $dtStart['VALUE'] = 'DATE';
327
328        $this->assertEquals("DTSTART;VALUE=DATE:20130607\r\n", $dtStart->serialize());
329
330    }
331
332    function testValidate() {
333
334        $exDate = $this->vcal->createProperty('EXDATE', '-00011130T143000Z');
335        $messages = $exDate->validate();
336        $this->assertEquals(1, count($messages));
337        $this->assertEquals(3, $messages[0]['level']);
338
339    }
340
341    /**
342     * This issue was discovered on the sabredav mailing list.
343     */
344    function testCreateDatePropertyThroughAdd() {
345
346        $vcal = new VCalendar();
347        $vevent = $vcal->add('VEVENT');
348
349        $dtstart = $vevent->add(
350            'DTSTART',
351            new \DateTime('2014-03-07'),
352            array('VALUE' => 'DATE')
353        );
354
355        $this->assertEquals("DTSTART;VALUE=DATE:20140307\r\n", $dtstart->serialize());
356
357    }
358
359}
360