Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
1 <?php 2 /** 3 * SimplePie 4 * 5 * A PHP-Based RSS and Atom Feed Framework. 6 * Takes the hard work out of managing a complete RSS/Atom solution. 7 * 8 * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without modification, are 12 * permitted provided that the following conditions are met: 13 * 14 * * Redistributions of source code must retain the above copyright notice, this list of 15 * conditions and the following disclaimer. 16 * 17 * * Redistributions in binary form must reproduce the above copyright notice, this list 18 * of conditions and the following disclaimer in the documentation and/or other materials 19 * provided with the distribution. 20 * 21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 22 * to endorse or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * @package SimplePie 36 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue 37 * @author Ryan Parman 38 * @author Geoffrey Sneddon 39 * @author Ryan McCue 40 * @link http://simplepie.org/ SimplePie 41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 42 */ 43 44 45 /** 46 * Date Parser 47 * 48 * @package SimplePie 49 * @subpackage Parsing 50 */ 51 class SimplePie_Parse_Date 52 { 53 /** 54 * Input data 55 * 56 * @access protected 57 * @var string 58 */ 59 var $date; 60 61 /** 62 * List of days, calendar day name => ordinal day number in the week 63 * 64 * @access protected 65 * @var array 66 */ 67 var $day = array( 68 // English 69 'mon' => 1, 70 'monday' => 1, 71 'tue' => 2, 72 'tuesday' => 2, 73 'wed' => 3, 74 'wednesday' => 3, 75 'thu' => 4, 76 'thursday' => 4, 77 'fri' => 5, 78 'friday' => 5, 79 'sat' => 6, 80 'saturday' => 6, 81 'sun' => 7, 82 'sunday' => 7, 83 // Dutch 84 'maandag' => 1, 85 'dinsdag' => 2, 86 'woensdag' => 3, 87 'donderdag' => 4, 88 'vrijdag' => 5, 89 'zaterdag' => 6, 90 'zondag' => 7, 91 // French 92 'lundi' => 1, 93 'mardi' => 2, 94 'mercredi' => 3, 95 'jeudi' => 4, 96 'vendredi' => 5, 97 'samedi' => 6, 98 'dimanche' => 7, 99 // German 100 'montag' => 1, 101 'dienstag' => 2, 102 'mittwoch' => 3, 103 'donnerstag' => 4, 104 'freitag' => 5, 105 'samstag' => 6, 106 'sonnabend' => 6, 107 'sonntag' => 7, 108 // Italian 109 'lunedì' => 1, 110 'martedì' => 2, 111 'mercoledì' => 3, 112 'giovedì' => 4, 113 'venerdì' => 5, 114 'sabato' => 6, 115 'domenica' => 7, 116 // Spanish 117 'lunes' => 1, 118 'martes' => 2, 119 'miércoles' => 3, 120 'jueves' => 4, 121 'viernes' => 5, 122 'sábado' => 6, 123 'domingo' => 7, 124 // Finnish 125 'maanantai' => 1, 126 'tiistai' => 2, 127 'keskiviikko' => 3, 128 'torstai' => 4, 129 'perjantai' => 5, 130 'lauantai' => 6, 131 'sunnuntai' => 7, 132 // Hungarian 133 'hétfő' => 1, 134 'kedd' => 2, 135 'szerda' => 3, 136 'csütörtok' => 4, 137 'péntek' => 5, 138 'szombat' => 6, 139 'vasárnap' => 7, 140 // Greek 141 'Δευ' => 1, 142 'Τρι' => 2, 143 'Τετ' => 3, 144 'Πεμ' => 4, 145 'Παρ' => 5, 146 'Σαβ' => 6, 147 'Κυρ' => 7, 148 // Russian 149 'Пн.' => 1, 150 'Вт.' => 2, 151 'Ср.' => 3, 152 'Чт.' => 4, 153 'Пт.' => 5, 154 'Сб.' => 6, 155 'Вс.' => 7, 156 ); 157 158 /** 159 * List of months, calendar month name => calendar month number 160 * 161 * @access protected 162 * @var array 163 */ 164 var $month = array( 165 // English 166 'jan' => 1, 167 'january' => 1, 168 'feb' => 2, 169 'february' => 2, 170 'mar' => 3, 171 'march' => 3, 172 'apr' => 4, 173 'april' => 4, 174 'may' => 5, 175 // No long form of May 176 'jun' => 6, 177 'june' => 6, 178 'jul' => 7, 179 'july' => 7, 180 'aug' => 8, 181 'august' => 8, 182 'sep' => 9, 183 'september' => 9, 184 'oct' => 10, 185 'october' => 10, 186 'nov' => 11, 187 'november' => 11, 188 'dec' => 12, 189 'december' => 12, 190 // Dutch 191 'januari' => 1, 192 'februari' => 2, 193 'maart' => 3, 194 'april' => 4, 195 'mei' => 5, 196 'juni' => 6, 197 'juli' => 7, 198 'augustus' => 8, 199 'september' => 9, 200 'oktober' => 10, 201 'november' => 11, 202 'december' => 12, 203 // French 204 'janvier' => 1, 205 'février' => 2, 206 'mars' => 3, 207 'avril' => 4, 208 'mai' => 5, 209 'juin' => 6, 210 'juillet' => 7, 211 'août' => 8, 212 'septembre' => 9, 213 'octobre' => 10, 214 'novembre' => 11, 215 'décembre' => 12, 216 // German 217 'januar' => 1, 218 'februar' => 2, 219 'märz' => 3, 220 'april' => 4, 221 'mai' => 5, 222 'juni' => 6, 223 'juli' => 7, 224 'august' => 8, 225 'september' => 9, 226 'oktober' => 10, 227 'november' => 11, 228 'dezember' => 12, 229 // Italian 230 'gennaio' => 1, 231 'febbraio' => 2, 232 'marzo' => 3, 233 'aprile' => 4, 234 'maggio' => 5, 235 'giugno' => 6, 236 'luglio' => 7, 237 'agosto' => 8, 238 'settembre' => 9, 239 'ottobre' => 10, 240 'novembre' => 11, 241 'dicembre' => 12, 242 // Spanish 243 'enero' => 1, 244 'febrero' => 2, 245 'marzo' => 3, 246 'abril' => 4, 247 'mayo' => 5, 248 'junio' => 6, 249 'julio' => 7, 250 'agosto' => 8, 251 'septiembre' => 9, 252 'setiembre' => 9, 253 'octubre' => 10, 254 'noviembre' => 11, 255 'diciembre' => 12, 256 // Finnish 257 'tammikuu' => 1, 258 'helmikuu' => 2, 259 'maaliskuu' => 3, 260 'huhtikuu' => 4, 261 'toukokuu' => 5, 262 'kesäkuu' => 6, 263 'heinäkuu' => 7, 264 'elokuu' => 8, 265 'suuskuu' => 9, 266 'lokakuu' => 10, 267 'marras' => 11, 268 'joulukuu' => 12, 269 // Hungarian 270 'január' => 1, 271 'február' => 2, 272 'március' => 3, 273 'április' => 4, 274 'május' => 5, 275 'június' => 6, 276 'július' => 7, 277 'augusztus' => 8, 278 'szeptember' => 9, 279 'október' => 10, 280 'november' => 11, 281 'december' => 12, 282 // Greek 283 'Ιαν' => 1, 284 'Φεβ' => 2, 285 'Μάώ' => 3, 286 'Μαώ' => 3, 287 'Απρ' => 4, 288 'Μάι' => 5, 289 'Μαϊ' => 5, 290 'Μαι' => 5, 291 'Ιούν' => 6, 292 'Ιον' => 6, 293 'Ιούλ' => 7, 294 'Ιολ' => 7, 295 'Αύγ' => 8, 296 'Αυγ' => 8, 297 'Σεπ' => 9, 298 'Οκτ' => 10, 299 'Νοέ' => 11, 300 'Δεκ' => 12, 301 // Russian 302 'Янв' => 1, 303 'января' => 1, 304 'Фев' => 2, 305 'февраля' => 2, 306 'Мар' => 3, 307 'марта' => 3, 308 'Апр' => 4, 309 'апреля' => 4, 310 'Май' => 5, 311 'мая' => 5, 312 'Июн' => 6, 313 'июня' => 6, 314 'Июл' => 7, 315 'июля' => 7, 316 'Авг' => 8, 317 'августа' => 8, 318 'Сен' => 9, 319 'сентября' => 9, 320 'Окт' => 10, 321 'октября' => 10, 322 'Ноя' => 11, 323 'ноября' => 11, 324 'Дек' => 12, 325 'декабря' => 12, 326 327 ); 328 329 /** 330 * List of timezones, abbreviation => offset from UTC 331 * 332 * @access protected 333 * @var array 334 */ 335 var $timezone = array( 336 'ACDT' => 37800, 337 'ACIT' => 28800, 338 'ACST' => 34200, 339 'ACT' => -18000, 340 'ACWDT' => 35100, 341 'ACWST' => 31500, 342 'AEDT' => 39600, 343 'AEST' => 36000, 344 'AFT' => 16200, 345 'AKDT' => -28800, 346 'AKST' => -32400, 347 'AMDT' => 18000, 348 'AMT' => -14400, 349 'ANAST' => 46800, 350 'ANAT' => 43200, 351 'ART' => -10800, 352 'AZOST' => -3600, 353 'AZST' => 18000, 354 'AZT' => 14400, 355 'BIOT' => 21600, 356 'BIT' => -43200, 357 'BOT' => -14400, 358 'BRST' => -7200, 359 'BRT' => -10800, 360 'BST' => 3600, 361 'BTT' => 21600, 362 'CAST' => 18000, 363 'CAT' => 7200, 364 'CCT' => 23400, 365 'CDT' => -18000, 366 'CEDT' => 7200, 367 'CEST' => 7200, 368 'CET' => 3600, 369 'CGST' => -7200, 370 'CGT' => -10800, 371 'CHADT' => 49500, 372 'CHAST' => 45900, 373 'CIST' => -28800, 374 'CKT' => -36000, 375 'CLDT' => -10800, 376 'CLST' => -14400, 377 'COT' => -18000, 378 'CST' => -21600, 379 'CVT' => -3600, 380 'CXT' => 25200, 381 'DAVT' => 25200, 382 'DTAT' => 36000, 383 'EADT' => -18000, 384 'EAST' => -21600, 385 'EAT' => 10800, 386 'ECT' => -18000, 387 'EDT' => -14400, 388 'EEST' => 10800, 389 'EET' => 7200, 390 'EGT' => -3600, 391 'EKST' => 21600, 392 'EST' => -18000, 393 'FJT' => 43200, 394 'FKDT' => -10800, 395 'FKST' => -14400, 396 'FNT' => -7200, 397 'GALT' => -21600, 398 'GEDT' => 14400, 399 'GEST' => 10800, 400 'GFT' => -10800, 401 'GILT' => 43200, 402 'GIT' => -32400, 403 'GST' => 14400, 404 'GST' => -7200, 405 'GYT' => -14400, 406 'HAA' => -10800, 407 'HAC' => -18000, 408 'HADT' => -32400, 409 'HAE' => -14400, 410 'HAP' => -25200, 411 'HAR' => -21600, 412 'HAST' => -36000, 413 'HAT' => -9000, 414 'HAY' => -28800, 415 'HKST' => 28800, 416 'HMT' => 18000, 417 'HNA' => -14400, 418 'HNC' => -21600, 419 'HNE' => -18000, 420 'HNP' => -28800, 421 'HNR' => -25200, 422 'HNT' => -12600, 423 'HNY' => -32400, 424 'IRDT' => 16200, 425 'IRKST' => 32400, 426 'IRKT' => 28800, 427 'IRST' => 12600, 428 'JFDT' => -10800, 429 'JFST' => -14400, 430 'JST' => 32400, 431 'KGST' => 21600, 432 'KGT' => 18000, 433 'KOST' => 39600, 434 'KOVST' => 28800, 435 'KOVT' => 25200, 436 'KRAST' => 28800, 437 'KRAT' => 25200, 438 'KST' => 32400, 439 'LHDT' => 39600, 440 'LHST' => 37800, 441 'LINT' => 50400, 442 'LKT' => 21600, 443 'MAGST' => 43200, 444 'MAGT' => 39600, 445 'MAWT' => 21600, 446 'MDT' => -21600, 447 'MESZ' => 7200, 448 'MEZ' => 3600, 449 'MHT' => 43200, 450 'MIT' => -34200, 451 'MNST' => 32400, 452 'MSDT' => 14400, 453 'MSST' => 10800, 454 'MST' => -25200, 455 'MUT' => 14400, 456 'MVT' => 18000, 457 'MYT' => 28800, 458 'NCT' => 39600, 459 'NDT' => -9000, 460 'NFT' => 41400, 461 'NMIT' => 36000, 462 'NOVST' => 25200, 463 'NOVT' => 21600, 464 'NPT' => 20700, 465 'NRT' => 43200, 466 'NST' => -12600, 467 'NUT' => -39600, 468 'NZDT' => 46800, 469 'NZST' => 43200, 470 'OMSST' => 25200, 471 'OMST' => 21600, 472 'PDT' => -25200, 473 'PET' => -18000, 474 'PETST' => 46800, 475 'PETT' => 43200, 476 'PGT' => 36000, 477 'PHOT' => 46800, 478 'PHT' => 28800, 479 'PKT' => 18000, 480 'PMDT' => -7200, 481 'PMST' => -10800, 482 'PONT' => 39600, 483 'PST' => -28800, 484 'PWT' => 32400, 485 'PYST' => -10800, 486 'PYT' => -14400, 487 'RET' => 14400, 488 'ROTT' => -10800, 489 'SAMST' => 18000, 490 'SAMT' => 14400, 491 'SAST' => 7200, 492 'SBT' => 39600, 493 'SCDT' => 46800, 494 'SCST' => 43200, 495 'SCT' => 14400, 496 'SEST' => 3600, 497 'SGT' => 28800, 498 'SIT' => 28800, 499 'SRT' => -10800, 500 'SST' => -39600, 501 'SYST' => 10800, 502 'SYT' => 7200, 503 'TFT' => 18000, 504 'THAT' => -36000, 505 'TJT' => 18000, 506 'TKT' => -36000, 507 'TMT' => 18000, 508 'TOT' => 46800, 509 'TPT' => 32400, 510 'TRUT' => 36000, 511 'TVT' => 43200, 512 'TWT' => 28800, 513 'UYST' => -7200, 514 'UYT' => -10800, 515 'UZT' => 18000, 516 'VET' => -14400, 517 'VLAST' => 39600, 518 'VLAT' => 36000, 519 'VOST' => 21600, 520 'VUT' => 39600, 521 'WAST' => 7200, 522 'WAT' => 3600, 523 'WDT' => 32400, 524 'WEST' => 3600, 525 'WFT' => 43200, 526 'WIB' => 25200, 527 'WIT' => 32400, 528 'WITA' => 28800, 529 'WKST' => 18000, 530 'WST' => 28800, 531 'YAKST' => 36000, 532 'YAKT' => 32400, 533 'YAPT' => 36000, 534 'YEKST' => 21600, 535 'YEKT' => 18000, 536 ); 537 538 /** 539 * Cached PCRE for SimplePie_Parse_Date::$day 540 * 541 * @access protected 542 * @var string 543 */ 544 var $day_pcre; 545 546 /** 547 * Cached PCRE for SimplePie_Parse_Date::$month 548 * 549 * @access protected 550 * @var string 551 */ 552 var $month_pcre; 553 554 /** 555 * Array of user-added callback methods 556 * 557 * @access private 558 * @var array 559 */ 560 var $built_in = array(); 561 562 /** 563 * Array of user-added callback methods 564 * 565 * @access private 566 * @var array 567 */ 568 var $user = array(); 569 570 /** 571 * Create new SimplePie_Parse_Date object, and set self::day_pcre, 572 * self::month_pcre, and self::built_in 573 * 574 * @access private 575 */ 576 public function __construct() 577 { 578 $this->day_pcre = '(' . implode('|', array_keys($this->day)) . ')'; 579 $this->month_pcre = '(' . implode('|', array_keys($this->month)) . ')'; 580 581 static $cache; 582 if (!isset($cache[get_class($this)])) 583 { 584 $all_methods = get_class_methods($this); 585 586 foreach ($all_methods as $method) 587 { 588 if (strtolower(substr($method, 0, 5)) === 'date_') 589 { 590 $cache[get_class($this)][] = $method; 591 } 592 } 593 } 594 595 foreach ($cache[get_class($this)] as $method) 596 { 597 $this->built_in[] = $method; 598 } 599 } 600 601 /** 602 * Get the object 603 * 604 * @access public 605 */ 606 public static function get() 607 { 608 static $object; 609 if (!$object) 610 { 611 $object = new SimplePie_Parse_Date; 612 } 613 return $object; 614 } 615 616 /** 617 * Parse a date 618 * 619 * @final 620 * @access public 621 * @param string $date Date to parse 622 * @return int Timestamp corresponding to date string, or false on failure 623 */ 624 public function parse($date) 625 { 626 foreach ($this->user as $method) 627 { 628 if (($returned = call_user_func($method, $date)) !== false) 629 { 630 return $returned; 631 } 632 } 633 634 foreach ($this->built_in as $method) 635 { 636 if (($returned = call_user_func(array($this, $method), $date)) !== false) 637 { 638 return $returned; 639 } 640 } 641 642 return false; 643 } 644 645 /** 646 * Add a callback method to parse a date 647 * 648 * @final 649 * @access public 650 * @param callback $callback 651 */ 652 public function add_callback($callback) 653 { 654 if (is_callable($callback)) 655 { 656 $this->user[] = $callback; 657 } 658 else 659 { 660 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING); 661 } 662 } 663 664 /** 665 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as 666 * well as allowing any of upper or lower case "T", horizontal tabs, or 667 * spaces to be used as the time separator (including more than one)) 668 * 669 * @access protected 670 * @return int Timestamp 671 */ 672 public function date_w3cdtf($date) 673 { 674 static $pcre; 675 if (!$pcre) 676 { 677 $year = '([0-9]{4})'; 678 $month = $day = $hour = $minute = $second = '([0-9]{2})'; 679 $decimal = '([0-9]*)'; 680 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))'; 681 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/'; 682 } 683 if (preg_match($pcre, $date, $match)) 684 { 685 /* 686 Capturing subpatterns: 687 1: Year 688 2: Month 689 3: Day 690 4: Hour 691 5: Minute 692 6: Second 693 7: Decimal fraction of a second 694 8: Zulu 695 9: Timezone ± 696 10: Timezone hours 697 11: Timezone minutes 698 */ 699 700 // Fill in empty matches 701 for ($i = count($match); $i <= 3; $i++) 702 { 703 $match[$i] = '1'; 704 } 705 706 for ($i = count($match); $i <= 7; $i++) 707 { 708 $match[$i] = '0'; 709 } 710 711 // Numeric timezone 712 if (isset($match[9]) && $match[9] !== '') 713 { 714 $timezone = $match[10] * 3600; 715 $timezone += $match[11] * 60; 716 if ($match[9] === '-') 717 { 718 $timezone = 0 - $timezone; 719 } 720 } 721 else 722 { 723 $timezone = 0; 724 } 725 726 // Convert the number of seconds to an integer, taking decimals into account 727 $second = round((int)$match[6] + (int)$match[7] / (10 ** strlen($match[7]))); 728 729 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone; 730 } 731 732 return false; 733 } 734 735 /** 736 * Remove RFC822 comments 737 * 738 * @access protected 739 * @param string $data Data to strip comments from 740 * @return string Comment stripped string 741 */ 742 public function remove_rfc2822_comments($string) 743 { 744 $string = (string) $string; 745 $position = 0; 746 $length = strlen($string); 747 $depth = 0; 748 749 $output = ''; 750 751 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) 752 { 753 $output .= substr($string, $position, $pos - $position); 754 $position = $pos + 1; 755 if ($pos === 0 || $string[$pos - 1] !== '\\') 756 { 757 $depth++; 758 while ($depth && $position < $length) 759 { 760 $position += strcspn($string, '()', $position); 761 if ($string[$position - 1] === '\\') 762 { 763 $position++; 764 continue; 765 } 766 elseif (isset($string[$position])) 767 { 768 switch ($string[$position]) 769 { 770 case '(': 771 $depth++; 772 break; 773 774 case ')': 775 $depth--; 776 break; 777 } 778 $position++; 779 } 780 else 781 { 782 break; 783 } 784 } 785 } 786 else 787 { 788 $output .= '('; 789 } 790 } 791 $output .= substr($string, $position); 792 793 return $output; 794 } 795 796 /** 797 * Parse RFC2822's date format 798 * 799 * @access protected 800 * @return int Timestamp 801 */ 802 public function date_rfc2822($date) 803 { 804 static $pcre; 805 if (!$pcre) 806 { 807 $wsp = '[\x09\x20]'; 808 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)'; 809 $optional_fws = $fws . '?'; 810 $day_name = $this->day_pcre; 811 $month = $this->month_pcre; 812 $day = '([0-9]{1,2})'; 813 $hour = $minute = $second = '([0-9]{2})'; 814 $year = '([0-9]{2,4})'; 815 $num_zone = '([+\-])([0-9]{2})([0-9]{2})'; 816 $character_zone = '([A-Z]{1,5})'; 817 $zone = '(?:' . $num_zone . '|' . $character_zone . ')'; 818 $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i'; 819 } 820 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) 821 { 822 /* 823 Capturing subpatterns: 824 1: Day name 825 2: Day 826 3: Month 827 4: Year 828 5: Hour 829 6: Minute 830 7: Second 831 8: Timezone ± 832 9: Timezone hours 833 10: Timezone minutes 834 11: Alphabetic timezone 835 */ 836 837 // Find the month number 838 $month = $this->month[strtolower($match[3])]; 839 840 // Numeric timezone 841 if ($match[8] !== '') 842 { 843 $timezone = $match[9] * 3600; 844 $timezone += $match[10] * 60; 845 if ($match[8] === '-') 846 { 847 $timezone = 0 - $timezone; 848 } 849 } 850 // Character timezone 851 elseif (isset($this->timezone[strtoupper($match[11])])) 852 { 853 $timezone = $this->timezone[strtoupper($match[11])]; 854 } 855 // Assume everything else to be -0000 856 else 857 { 858 $timezone = 0; 859 } 860 861 // Deal with 2/3 digit years 862 if ($match[4] < 50) 863 { 864 $match[4] += 2000; 865 } 866 elseif ($match[4] < 1000) 867 { 868 $match[4] += 1900; 869 } 870 871 // Second is optional, if it is empty set it to zero 872 if ($match[7] !== '') 873 { 874 $second = $match[7]; 875 } 876 else 877 { 878 $second = 0; 879 } 880 881 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone; 882 } 883 884 return false; 885 } 886 887 /** 888 * Parse RFC850's date format 889 * 890 * @access protected 891 * @return int Timestamp 892 */ 893 public function date_rfc850($date) 894 { 895 static $pcre; 896 if (!$pcre) 897 { 898 $space = '[\x09\x20]+'; 899 $day_name = $this->day_pcre; 900 $month = $this->month_pcre; 901 $day = '([0-9]{1,2})'; 902 $year = $hour = $minute = $second = '([0-9]{2})'; 903 $zone = '([A-Z]{1,5})'; 904 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i'; 905 } 906 if (preg_match($pcre, $date, $match)) 907 { 908 /* 909 Capturing subpatterns: 910 1: Day name 911 2: Day 912 3: Month 913 4: Year 914 5: Hour 915 6: Minute 916 7: Second 917 8: Timezone 918 */ 919 920 // Month 921 $month = $this->month[strtolower($match[3])]; 922 923 // Character timezone 924 if (isset($this->timezone[strtoupper($match[8])])) 925 { 926 $timezone = $this->timezone[strtoupper($match[8])]; 927 } 928 // Assume everything else to be -0000 929 else 930 { 931 $timezone = 0; 932 } 933 934 // Deal with 2 digit year 935 if ($match[4] < 50) 936 { 937 $match[4] += 2000; 938 } 939 else 940 { 941 $match[4] += 1900; 942 } 943 944 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; 945 } 946 947 return false; 948 } 949 950 /** 951 * Parse C99's asctime()'s date format 952 * 953 * @access protected 954 * @return int Timestamp 955 */ 956 public function date_asctime($date) 957 { 958 static $pcre; 959 if (!$pcre) 960 { 961 $space = '[\x09\x20]+'; 962 $wday_name = $this->day_pcre; 963 $mon_name = $this->month_pcre; 964 $day = '([0-9]{1,2})'; 965 $hour = $sec = $min = '([0-9]{2})'; 966 $year = '([0-9]{4})'; 967 $terminator = '\x0A?\x00?'; 968 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i'; 969 } 970 if (preg_match($pcre, $date, $match)) 971 { 972 /* 973 Capturing subpatterns: 974 1: Day name 975 2: Month 976 3: Day 977 4: Hour 978 5: Minute 979 6: Second 980 7: Year 981 */ 982 983 $month = $this->month[strtolower($match[2])]; 984 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]); 985 } 986 987 return false; 988 } 989 990 /** 991 * Parse dates using strtotime() 992 * 993 * @access protected 994 * @return int Timestamp 995 */ 996 public function date_strtotime($date) 997 { 998 $strtotime = strtotime($date); 999 if ($strtotime === -1 || $strtotime === false) 1000 { 1001 return false; 1002 } 1003 1004 return $strtotime; 1005 } 1006 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body