58 for ( $i = 1; $i <= 12; $i++ ) {
59 $this->xMonths[$this->lang->lc( $this->lang->getMonthName( $i ) )] = $i;
60 $this->xMonths[$this->lang->lc( $this->lang->getMonthAbbreviation( $i ) )] = $i;
63 $this->regexTrail =
'(?![a-z])/iu';
65 # Partial regular expressions
66 $this->prxDM =
'\[\[(\d{1,2})[ _](' . $this->monthNames .
')\]\]';
67 $this->prxMD =
'\[\[(' . $this->monthNames .
')[ _](\d{1,2})\]\]';
68 $this->prxY =
'\[\[(\d{1,4}([ _]BC|))\]\]';
69 $this->prxISO1 =
'\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})\]\]';
70 $this->prxISO2 =
'\[\[(-?\d{4})-(\d{2})-(\d{2})\]\]';
72 # Real regular expressions
73 $this->regexes[
self::DMY] =
"/{$this->prxDM}(?: *, *| +){$this->prxY}{$this->regexTrail}";
74 $this->regexes[
self::YDM] =
"/{$this->prxY}(?: *, *| +){$this->prxDM}{$this->regexTrail}";
75 $this->regexes[
self::MDY] =
"/{$this->prxMD}(?: *, *| +){$this->prxY}{$this->regexTrail}";
76 $this->regexes[
self::YMD] =
"/{$this->prxY}(?: *, *| +){$this->prxMD}{$this->regexTrail}";
77 $this->regexes[
self::DM] =
"/{$this->prxDM}{$this->regexTrail}";
78 $this->regexes[
self::MD] =
"/{$this->prxMD}{$this->regexTrail}";
79 $this->regexes[
self::ISO1] =
"/{$this->prxISO1}{$this->regexTrail}";
80 $this->regexes[
self::ISO2] =
"/{$this->prxISO2}{$this->regexTrail}";
83 # See the comments in replace() for the meaning of the letters
90 $this->keys[
self::ISO1] =
'ymd'; # y means ISO year
94 $this->targets[
self::DMY] =
'[[F j|j F]] [[Y]]';
95 $this->targets[
self::YDM] =
'[[Y]], [[F j|j F]]';
96 $this->targets[
self::MDY] =
'[[F j]], [[Y]]';
97 $this->targets[
self::YMD] =
'[[Y]] [[F j]]';
98 $this->targets[
self::DM] =
'[[F j|j F]]';
99 $this->targets[
self::MD] =
'[[F j]]';
100 $this->targets[
self::ISO1] =
'[[Y|y]]-[[F j|m-d]]';
111 $this->preferences =
array(
112 'default' => self::NONE,
116 'ISO 8601' => self::ISO1,
129 static $dateFormatter =
false;
132 if ( !$dateFormatter ) {
133 $dateFormatter =
$wgMemc->get( $key );
134 if ( !$dateFormatter ) {
136 $wgMemc->set( $key, $dateFormatter, 3600 );
139 return $dateFormatter;
150 $linked = in_array(
'linked',
$options );
151 $match_whole = in_array(
'match-whole',
$options );
153 if ( isset( $this->preferences[$preference] ) ) {
154 $preference = $this->preferences[$preference];
160 if ( isset( $this->rules[$preference][$i] ) ) {
162 $this->mTarget = $this->rules[$preference][$i];
163 } elseif ( isset( $this->rules[self::ALL][$i] ) ) {
165 $this->mTarget = $this->rules[
self::ALL][$i];
166 } elseif ( $preference ) {
168 $this->mTarget = $preference;
173 $regex = $this->regexes[$i];
177 $regex = str_replace(
array(
'\[\[',
'\]\]' ),
'', $regex );
180 if ( $match_whole ) {
182 $regex = preg_replace(
'!^/!',
'/^', $regex );
183 $regex = str_replace( $this->regexTrail,
184 '$' . $this->regexTrail, $regex );
188 $this->mLinked = $linked;
189 $text = preg_replace_callback( $regex,
array( &$this,
'replace' ), $text );
190 unset( $this->mLinked );
200 # Extract information from $matches
202 if ( isset( $this->mLinked ) ) {
203 $linked = $this->mLinked;
208 for ( $p = 0; $p < strlen( $key ); $p++ ) {
209 if ( $key[$p] !=
' ' ) {
227 $format = preg_replace(
'/\[\[[^|]+\|([^\]]+)\]\]/',
'$1', $format );
229 $format = str_replace(
array(
'[[',
']]' ),
'', $format );
237 if ( !isset( $bits[
'y'] ) && isset( $bits[
'Y'] ) ) {
240 if ( !isset( $bits[
'Y'] ) && isset( $bits[
'y'] ) ) {
244 if ( !isset( $bits[
'm'] ) ) {
246 if ( !$m || $m ==
'00' ) {
253 if ( !isset( $bits[
'd'] ) ) {
254 $bits[
'd'] = sprintf(
'%02d', $bits[
'j'] );
257 for ( $p = 0; $p < strlen( $format ); $p++ ) {
260 case 'd': # ISO day
of month
263 case 'm': # ISO month
269 case 'j': # ordinary day
of month
270 if ( !isset( $bits[
'j'] ) ) {
271 $text .= intval( $bits[
'd'] );
276 case 'F': #
long month
277 if ( !isset( $bits[
'F'] ) ) {
278 $m = intval( $bits[
'm'] );
279 if ( $m > 12 || $m < 1 ) {
282 $text .= $this->lang->getMonthName( $m );
285 $text .= ucfirst( $bits[
'F'] );
288 case 'Y': # ordinary (optional BC) year
300 if ( isset( $bits[
'y'] ) ) {
301 $isoBits[] = $bits[
'y'];
303 $isoBits[] = $bits[
'm'];
304 $isoBits[] = $bits[
'd'];
305 $isoDate = implode(
'-', $isoBits );
309 array(
'class' =>
'mw-formatted-date',
'title' => $isoDate ), $text );
320 for ( $i = 1; $i <= 12; $i++ ) {
321 $names[] = $this->lang->getMonthName( $i );
322 $names[] = $this->lang->getMonthAbbreviation( $i );
324 return implode(
'|', $names );
333 $n = $this->xMonths[$this->lang->lc( $monthName )];
334 return sprintf(
'%02d',
$n );
343 # Assumes the year is in a nice format, as enforced by the regex
344 if ( substr( $year, -2 ) ==
'BC' ) {
345 $num = intval( substr( $year, 0, -3 ) ) - 1;
346 # PHP bug note: sprintf( "%04d", -1 ) fails poorly
347 $text = sprintf(
'-%04d', $num );
350 $text = sprintf(
'%04d', $year );
360 if ( $iso[0] ==
'-' ) {
361 $text = ( intval( substr( $iso, 1 ) ) + 1 ) .
' BC';
363 $text = intval( $iso );