[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/SimplePie/Parse/ -> Date.php (source)

   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  }


Generated: Thu Mar 28 01:00:02 2024 Cross-referenced by PHPXref 0.7.1