PluginProbe
FeedWordPress / trunk
FeedWordPress vtrunk
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
feedwordpress / feedtime.class.php

feedtime.class.php in FeedWordPress trunk, at feedtime.class.php

158 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * class FeedTime: handle common date-time formats used in feeds.
4 * We will try to be as tolerant as possible of different representations, since
5 * RSS Is A Fucking Mess, broken dates seem to be especially pervasive, etc.
6 * Supports anything that your version of PHP's strtotime() can handle; also has
7 * a built-in parser for W3C DTF, in case your PHP doesn't have that.
8 *
9 * Tries to parse a W3C DTF first; then falls back to strtotime(). If strtotime
10 * fails due to a mystery timezone, then we will try again on local time, with
11 * the timezone stripped out.
12 *
13 * To parse a string representation of a date-time from a feed, instantiate and
14 * then pull the timestamp:
15 *
16 * $time = new FeedTime($s);
17 * if ( ! $time->failed()) :
18 * $ts = $time->timestamp();
19 * else :
20 * // ...
21 * endif;
22 */
23 class FeedTime {
24 var $rep;
25 var $ts;
26
27 function __construct( $time ) {
28 $this->set($time);
29 } /* FeedTime constructor */
30
31 function FeedTime( $time ) {
32 self::__construct( $time );
33 }
34
35 function set ($time, $recurse = false) {
36 $this->rep = $time;
37 $this->ts = NULL;
38 if (is_numeric($time)) : // Presumably a Unix-epoch timestamp
39 $this->ts = $this->rep;
40 elseif (is_string($time)) :
41 // First, try to parse it as a W3C date-time
42 $this->ts = $this->parse_w3cdtf();
43
44 if ($this->failed()) :
45 // In some versions of PHP, strtotime() does not
46 // support the UT timezone. But since UT is by
47 // definition within 1 second of UTC, we'll just
48 // convert it preemptively to avoid problems.
49 $time = preg_replace(
50 '/(\s)UT$/',
51 '$1UTC',
52 $time
53 );
54 $this->ts = strtotime($time);
55
56 if ($this->failed()
57 and preg_match('/^(.*)([+\-][0-9]+|\s+[A-Za-z]{1,3})$/', $time, $matches)) :
58 // Try dropping the time zone and recurse
59 $this->set($matches[1], /*recurse=*/ true);
60 endif;
61 endif;
62 endif;
63 } /* FeedTime::set() */
64
65 function timestamp () {
66 $unix = NULL;
67 if ( ! $this->failed()) :
68 $unix = $this->ts;
69 endif;
70 return $unix;
71 } /* FeedTime::timestamp() */
72
73 function failed () {
74 return ( !is_numeric($this->ts) or ! $this->ts or ($this->ts <= 0));
75 } /* FeedTime::failed() */
76
77 /**
78 * FeedTime::parse_w3cdtf() parses a W3C date-time format date into a
79 * Unix epoch timestamp. Derived from the parse_w3cdtf function included
80 * with MagpieRSS by Kellan Elliot-McCrea <kellan@protest.net>, with
81 * modifications and bugfixes by Charles Johnson
82 * <technophilia@radgeek.com>, under the terms of the GPL.
83 */
84 function parse_w3cdtf () {
85 $unix = NULL; // Failure
86
87 # regex to match wc3dtf
88 $pat = "/^\s*
89 (\d{4})
90 (-
91 (\d{2})
92 (-
93 (\d{2})
94 (T
95 (\d{2})
96 :(\d{2})
97 (:
98 (\d{2})
99 (\.\d+)?
100 )?
101 (?:([-+])(\d{2}):?(\d{2})|(Z))?
102 )?
103 )?
104 )?
105 \s*\$
106 /x";
107
108 if ( preg_match( $pat, $this->rep, $match ) ) :
109 $year = (isset($match[1]) ? $match[1] : NULL);
110 $month = (isset($match[3]) ? $match[3] : NULL);
111 $day = (isset($match[5]) ? $match[5] : NULL);
112 $hours = (isset($match[7]) ? $match[7] : NULL);
113 $minutes = (isset($match[8]) ? $match[8] : NULL);
114 $seconds = (isset($match[10]) ? $match[10] : NULL);
115
116 # W3C dates can omit the time, the day of the month, or even the month.
117 # Fill in any blanks using information from the present moment. --CWJ
118 $default['hr'] = (int) gmdate('H');
119 $default['day'] = (int) gmdate('d');
120 $default['month'] = (int) gmdate('m');
121
122 if (is_null($hours)) : $hours = $default['hr']; $minutes = 0; $seconds = 0; endif;
123 if (is_null($day)) : $day = $default['day']; endif;
124 if (is_null($month)) : $month = $default['month']; endif;
125
126 # calc epoch for current date assuming GMT
127 $unix = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
128
129 $offset = 0;
130 if ( isset($match[15]) and $match[15] == 'Z' ) :
131 # zulu time, aka GMT
132 else :
133 $tz_mod = (isset($match[12]) ? $match[12] : NULL);
134 $tz_hour = (isset($match[13]) ? $match[13] : NULL);
135 $tz_min = (isset($match[14]) ? $match[14] : NULL);
136
137 # zero out the variables
138 if ( is_null($tz_hour) ) :
139 $offset = (int) get_option('gmt_offset');
140 $tz_hour = abs($offset);
141 $tz_mod = ((abs($offset) != $offset) ? '-' : '+');
142 endif;
143 if ( is_null($tz_min) ) : $tz_min = 0; endif;
144
145 $offset_secs = (($tz_hour*60)+$tz_min)*60;
146
147 # is timezone ahead of GMT? then subtract offset
148 if ( $tz_mod == '+' ) :
149 $offset_secs = $offset_secs * -1;
150 endif;
151 $offset = $offset_secs;
152 endif;
153 $unix = $unix + $offset;
154 endif;
155 return $unix;
156 } /* FeedTime::parse_w3cdtf () */
157 } /* class FeedTime */
158