SimplePie: PHP-based RSS and Atom feed handling
 
  • Overview
  • Demo
  • Blog
  • Download
  • Documentation
  • API Docs
  • Support
  • Issue Tracker
  • FAQ
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated

Packages

  • SimplePie
    • API
    • Caching
    • HTTP
    • Parsing

Classes

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

Show some love! Wishlists for Geoffrey, Ryan P., and Ryan M.

SimplePie is © 2004–2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue and contributors. Licensed under the BSD License. Hosted thanks to Matt Mullenweg, API documentation generated by ApiGen 2.6.1. Variation on the Feed Icon by Wolfgang Bartelme.