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