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