Projet

Général

Profil

Paste
Télécharger (19,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / libraries / simplepie / library / SimplePie / Parse / Date.php @ 41cc1b08

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.1
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