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