1<?php 2 3namespace Sabre\VObject; 4 5class TimeZoneUtilTest extends \PHPUnit_Framework_TestCase { 6 7 function setUp() { 8 9 // clearning the tz cache 10 TimezoneUtil::$map = null; 11 12 } 13 14 /** 15 * @dataProvider getMapping 16 */ 17 function testCorrectTZ($timezoneName) { 18 19 try { 20 $tz = new \DateTimeZone($timezoneName); 21 $this->assertInstanceOf('DateTimeZone', $tz); 22 } catch (\Exception $e) { 23 if (strpos($e->getMessage(), "Unknown or bad timezone") !== false) { 24 $this->markTestSkipped($timezoneName . ' is not (yet) supported in this PHP version. Update pecl/timezonedb'); 25 } else { 26 throw $e; 27 } 28 29 } 30 31 } 32 33 function getMapping() { 34 35 TimeZoneUtil::loadTzMaps(); 36 37 // PHPUNit requires an array of arrays 38 return array_map( 39 function($value) { 40 return [$value]; 41 }, 42 TimeZoneUtil::$map 43 ); 44 45 } 46 47 function testExchangeMap() { 48 49 $vobj = <<<HI 50BEGIN:VCALENDAR 51METHOD:REQUEST 52VERSION:2.0 53BEGIN:VTIMEZONE 54TZID:foo 55X-MICROSOFT-CDO-TZID:2 56BEGIN:STANDARD 57DTSTART:16010101T030000 58TZOFFSETFROM:+0200 59TZOFFSETTO:+0100 60RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU 61END:STANDARD 62BEGIN:DAYLIGHT 63DTSTART:16010101T020000 64TZOFFSETFROM:+0100 65TZOFFSETTO:+0200 66RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU 67END:DAYLIGHT 68END:VTIMEZONE 69BEGIN:VEVENT 70DTSTAMP:20120416T092149Z 71DTSTART;TZID="foo":20120418T1 72 00000 73SUMMARY:Begin Unterhaltsreinigung 74UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000 75 0100000008FECD2E607780649BE5A4C9EE6418CBC 76 000 77END:VEVENT 78END:VCALENDAR 79HI; 80 81 $tz = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj)); 82 $ex = new \DateTimeZone('Europe/Lisbon'); 83 84 $this->assertEquals($ex->getName(), $tz->getName()); 85 86 } 87 88 function testWetherMicrosoftIsStillInsane() { 89 90 $vobj = <<<HI 91BEGIN:VCALENDAR 92METHOD:REQUEST 93VERSION:2.0 94BEGIN:VTIMEZONE 95TZID:(GMT+01.00) Sarajevo/Warsaw/Zagreb 96X-MICROSOFT-CDO-TZID:2 97BEGIN:STANDARD 98DTSTART:16010101T030000 99TZOFFSETFROM:+0200 100TZOFFSETTO:+0100 101RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU 102END:STANDARD 103END:VTIMEZONE 104END:VCALENDAR 105HI; 106 107 $tz = TimeZoneUtil::getTimeZone('(GMT+01.00) Sarajevo/Warsaw/Zagreb', Reader::read($vobj)); 108 $ex = new \DateTimeZone('Europe/Sarajevo'); 109 110 $this->assertEquals($ex->getName(), $tz->getName()); 111 112 } 113 114 function testUnknownExchangeId() { 115 116 $vobj = <<<HI 117BEGIN:VCALENDAR 118METHOD:REQUEST 119VERSION:2.0 120BEGIN:VTIMEZONE 121TZID:foo 122X-MICROSOFT-CDO-TZID:2000 123BEGIN:STANDARD 124DTSTART:16010101T030000 125TZOFFSETFROM:+0200 126TZOFFSETTO:+0100 127RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU 128END:STANDARD 129BEGIN:DAYLIGHT 130DTSTART:16010101T020000 131TZOFFSETFROM:+0100 132TZOFFSETTO:+0200 133RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU 134END:DAYLIGHT 135END:VTIMEZONE 136BEGIN:VEVENT 137DTSTAMP:20120416T092149Z 138DTSTART;TZID="foo":20120418T1 139 00000 140SUMMARY:Begin Unterhaltsreinigung 141UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000 142 0100000008FECD2E607780649BE5A4C9EE6418CBC 143DTEND;TZID="Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb":20120418T103 144 000 145END:VEVENT 146END:VCALENDAR 147HI; 148 149 $tz = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj)); 150 $ex = new \DateTimeZone(date_default_timezone_get()); 151 $this->assertEquals($ex->getName(), $tz->getName()); 152 153 } 154 155 function testWindowsTimeZone() { 156 157 $tz = TimeZoneUtil::getTimeZone('Eastern Standard Time'); 158 $ex = new \DateTimeZone('America/New_York'); 159 $this->assertEquals($ex->getName(), $tz->getName()); 160 161 } 162 163 /** 164 * @dataProvider getPHPTimeZoneIdentifiers 165 */ 166 function testTimeZoneIdentifiers($tzid) { 167 168 $tz = TimeZoneUtil::getTimeZone($tzid); 169 $ex = new \DateTimeZone($tzid); 170 171 $this->assertEquals($ex->getName(), $tz->getName()); 172 173 } 174 175 /** 176 * @dataProvider getPHPTimeZoneBCIdentifiers 177 */ 178 function testTimeZoneBCIdentifiers($tzid) { 179 180 $tz = TimeZoneUtil::getTimeZone($tzid); 181 $ex = new \DateTimeZone($tzid); 182 183 $this->assertEquals($ex->getName(), $tz->getName()); 184 185 } 186 187 function getPHPTimeZoneIdentifiers() { 188 189 // PHPUNit requires an array of arrays 190 return array_map( 191 function($value) { 192 return [$value]; 193 }, 194 \DateTimeZone::listIdentifiers() 195 ); 196 197 } 198 199 function getPHPTimeZoneBCIdentifiers() { 200 201 // PHPUNit requires an array of arrays 202 return array_map( 203 function($value) { 204 return [$value]; 205 }, 206 TimeZoneUtil::getIdentifiersBC() 207 ); 208 209 } 210 211 function testTimezoneOffset() { 212 213 $tz = TimeZoneUtil::getTimeZone('GMT-0400', null, true); 214 215 if (version_compare(PHP_VERSION, '5.5.10', '>=') && !defined('HHVM_VERSION')) { 216 $ex = new \DateTimeZone('-04:00'); 217 } else { 218 $ex = new \DateTimeZone('Etc/GMT-4'); 219 } 220 $this->assertEquals($ex->getName(), $tz->getName()); 221 222 } 223 224 /** 225 * @expectedException InvalidArgumentException 226 */ 227 function testTimezoneFail() { 228 229 $tz = TimeZoneUtil::getTimeZone('FooBar', null, true); 230 231 } 232 233 function testFallBack() { 234 235 $vobj = <<<HI 236BEGIN:VCALENDAR 237METHOD:REQUEST 238VERSION:2.0 239BEGIN:VTIMEZONE 240TZID:foo 241BEGIN:STANDARD 242DTSTART:16010101T030000 243TZOFFSETFROM:+0200 244TZOFFSETTO:+0100 245RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU 246END:STANDARD 247BEGIN:DAYLIGHT 248DTSTART:16010101T020000 249TZOFFSETFROM:+0100 250TZOFFSETTO:+0200 251RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU 252END:DAYLIGHT 253END:VTIMEZONE 254BEGIN:VEVENT 255DTSTAMP:20120416T092149Z 256DTSTART;TZID="foo":20120418T1 257 00000 258SUMMARY:Begin Unterhaltsreinigung 259UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000 260 0100000008FECD2E607780649BE5A4C9EE6418CBC 261 000 262END:VEVENT 263END:VCALENDAR 264HI; 265 266 $tz = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj)); 267 $ex = new \DateTimeZone(date_default_timezone_get()); 268 $this->assertEquals($ex->getName(), $tz->getName()); 269 270 } 271 272 function testLjubljanaBug() { 273 274 $vobj = <<<HI 275BEGIN:VCALENDAR 276CALSCALE:GREGORIAN 277PRODID:-//Ximian//NONSGML Evolution Calendar//EN 278VERSION:2.0 279BEGIN:VTIMEZONE 280TZID:/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana 281X-LIC-LOCATION:Europe/Ljubljana 282BEGIN:STANDARD 283TZNAME:CET 284DTSTART:19701028T030000 285RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 286TZOFFSETFROM:+0200 287TZOFFSETTO:+0100 288END:STANDARD 289BEGIN:DAYLIGHT 290TZNAME:CEST 291DTSTART:19700325T020000 292RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 293TZOFFSETFROM:+0100 294TZOFFSETTO:+0200 295END:DAYLIGHT 296END:VTIMEZONE 297BEGIN:VEVENT 298UID:foo 299DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana: 300 20121003T080000 301DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana: 302 20121003T083000 303TRANSP:OPAQUE 304SEQUENCE:2 305SUMMARY:testing 306CREATED:20121002T172613Z 307LAST-MODIFIED:20121002T172613Z 308END:VEVENT 309END:VCALENDAR 310 311HI; 312 313 314 $tz = TimeZoneUtil::getTimeZone('/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana', Reader::read($vobj)); 315 $ex = new \DateTimeZone('Europe/Ljubljana'); 316 $this->assertEquals($ex->getName(), $tz->getName()); 317 318 } 319 320 function testWeirdSystemVLICs() { 321 322$vobj = <<<HI 323BEGIN:VCALENDAR 324CALSCALE:GREGORIAN 325PRODID:-//Ximian//NONSGML Evolution Calendar//EN 326VERSION:2.0 327BEGIN:VTIMEZONE 328TZID:/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT 329X-LIC-LOCATION:SystemV/EST5EDT 330BEGIN:STANDARD 331TZNAME:EST 332DTSTART:19701104T020000 333RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11 334TZOFFSETFROM:-0400 335TZOFFSETTO:-0500 336END:STANDARD 337BEGIN:DAYLIGHT 338TZNAME:EDT 339DTSTART:19700311T020000 340RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3 341TZOFFSETFROM:-0500 342TZOFFSETTO:-0400 343END:DAYLIGHT 344END:VTIMEZONE 345BEGIN:VEVENT 346UID:20121026T021107Z-6301-1000-1-0@chAir 347DTSTAMP:20120905T172126Z 348DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT: 349 20121026T153000 350DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT: 351 20121026T160000 352TRANSP:OPAQUE 353SEQUENCE:5 354SUMMARY:pick up Ibby 355CLASS:PUBLIC 356CREATED:20121026T021108Z 357LAST-MODIFIED:20121026T021118Z 358X-EVOLUTION-MOVE-CALENDAR:1 359END:VEVENT 360END:VCALENDAR 361HI; 362 363 $tz = TimeZoneUtil::getTimeZone('/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT', Reader::read($vobj), true); 364 $ex = new \DateTimeZone('America/New_York'); 365 $this->assertEquals($ex->getName(), $tz->getName()); 366 367 } 368 369 370 function testPrefixedOffsetExchangeIdentifier() 371 { 372 $tz = TimeZoneUtil::getTimeZone('(UTC-05:00) Eastern Time (US & Canada)'); 373 $ex = new \DateTimeZone('America/New_York'); 374 $this->assertEquals($ex->getName(), $tz->getName()); 375 } 376 377} 378