Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

DateFormatter.php

Go to the documentation of this file.
00001 <?php 00002 define("DF_ALL", -1); 00003 define("DF_NONE", 0); 00004 define("DF_MDY", 1); 00005 define("DF_DMY", 2); 00006 define("DF_YMD", 3); 00007 define("DF_ISO1", 4); 00008 define("DF_LASTPREF", 4); 00009 00010 define("DF_ISO2", 5); 00011 define("DF_YDM", 6); 00012 define("DF_DM", 7); 00013 define("DF_MD", 8); 00014 define("DF_LAST", 8); 00015 00016 # To do: preferences, OutputPage 00017 00018 class DateFormatter 00019 { 00020 var $mSource, $mTarget; 00021 var $monthNames = '', $rxDM, $rxMD, $rxDMY, $rxYDM, $rxMDY, $rxYMD; 00022 00023 var $regexes, $pDays, $pMonths, $pYears; 00024 var $rules, $xMonths; 00025 00026 function DateFormatter() 00027 { 00028 global $wgMonthNamesEn, $wgInputEncoding; 00029 00030 $this->monthNames = $this->getMonthRegex(); 00031 for ( $i=1; $i<=12; $i++ ) { 00032 $this->xMonths[strtolower( $wgMonthNamesEn[$i-1] )] = $i; 00033 } 00034 00035 # Attempt at UTF-8 support, untested at the moment 00036 if ( $wgInputEncoding == 'UTF-8' ) { 00037 $this->regexTrail = '(?![a-z])/iu'; 00038 } else { 00039 $this->regexTrail = '(?![a-z])/i'; 00040 } 00041 00042 # Partial regular expressions 00043 $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')]]'; 00044 $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})]]'; 00045 $this->prxY = '\[\[(\d{1,4}([ _]BC|))]]'; 00046 $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})]]'; 00047 $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})]]'; 00048 00049 # Real regular expressions 00050 $this->regexes[DF_DMY] = "/{$this->prxDM} *,? *{$this->prxY}{$this->regexTrail}"; 00051 $this->regexes[DF_YDM] = "/{$this->prxY} *,? *{$this->prxDM}{$this->regexTrail}"; 00052 $this->regexes[DF_MDY] = "/{$this->prxMD} *,? *{$this->prxY}{$this->regexTrail}"; 00053 $this->regexes[DF_YMD] = "/{$this->prxY} *,? *{$this->prxMD}{$this->regexTrail}"; 00054 $this->regexes[DF_DM] = "/{$this->prxDM}{$this->regexTrail}"; 00055 $this->regexes[DF_MD] = "/{$this->prxMD}{$this->regexTrail}"; 00056 $this->regexes[DF_ISO1] = "/{$this->prxISO1}{$this->regexTrail}"; 00057 $this->regexes[DF_ISO2] = "/{$this->prxISO2}{$this->regexTrail}"; 00058 00059 # Extraction keys 00060 # See the comments in replace() for the meaning of the letters 00061 $this->keys[DF_DMY] = 'jFY'; 00062 $this->keys[DF_YDM] = 'Y jF'; 00063 $this->keys[DF_MDY] = 'FjY'; 00064 $this->keys[DF_YMD] = 'Y Fj'; 00065 $this->keys[DF_DM] = 'jF'; 00066 $this->keys[DF_MD] = 'Fj'; 00067 $this->keys[DF_ISO1] = 'ymd'; # y means ISO year 00068 $this->keys[DF_ISO2] = 'ymd'; 00069 00070 # Target date formats 00071 $this->targets[DF_DMY] = '[[F j|j F]] [[Y]]'; 00072 $this->targets[DF_YDM] = '[[Y]], [[F j|j F]]'; 00073 $this->targets[DF_MDY] = '[[F j]], [[Y]]'; 00074 $this->targets[DF_YMD] = '[[Y]] [[F j]]'; 00075 $this->targets[DF_DM] = '[[F j|j F]]'; 00076 $this->targets[DF_MD] = '[[F j]]'; 00077 $this->targets[DF_ISO1] = '[[Y|y]]-[[F j|m-d]]'; 00078 $this->targets[DF_ISO2] = '[[y-m-d]]'; 00079 00080 # Rules 00081 # pref source target 00082 $this->rules[DF_DMY][DF_MD] = DF_DM; 00083 $this->rules[DF_ALL][DF_MD] = DF_MD; 00084 $this->rules[DF_MDY][DF_DM] = DF_MD; 00085 $this->rules[DF_ALL][DF_DM] = DF_DM; 00086 $this->rules[DF_NONE][DF_ISO2] = DF_ISO1; 00087 } 00088 00089 function reformat( $preference, $text ) 00090 { 00091 for ( $i=1; $i<=DF_LAST; $i++ ) { 00092 $this->mSource = $i; 00093 if ( @$this->rules[$preference][$i] ) { 00094 # Specific rules 00095 $this->mTarget = $this->rules[$preference][$i]; 00096 } elseif ( @$this->rules[DF_ALL][$i] ) { 00097 # General rules 00098 $this->mTarget = $this->rules[DF_ALL][$i]; 00099 } elseif ( $preference ) { 00100 # User preference 00101 $this->mTarget = $preference; 00102 } else { 00103 # Default 00104 $this->mTarget = $i; 00105 } 00106 $text = preg_replace_callback( $this->regexes[$i], 'wfMainDateReplace', $text ); 00107 } 00108 return $text; 00109 } 00110 00111 function replace( $matches ) 00112 { 00113 global $wgMonthNamesEn; 00114 # Extract information from $matches 00115 $bits = array(); 00116 $key = $this->keys[$this->mSource]; 00117 for ( $p=0; $p < strlen($key); $p++ ) { 00118 if ( $key{$p} != ' ' ) { 00119 $bits[$key{$p}] = $matches[$p+1]; 00120 } 00121 } 00122 00123 $format = $this->targets[$this->mTarget]; 00124 00125 # Construct new date 00126 $text = ''; 00127 $fail = false; 00128 00129 for ( $p=0; $p < strlen( $format ); $p++ ) { 00130 $char = $format{$p}; 00131 switch ( $char ) { 00132 case 'd': # ISO day of month 00133 if ( is_null($bits['d']) ) { 00134 $text .= sprintf( '%02d', $bits['j'] ); 00135 } else { 00136 $text .= $bits['d']; 00137 } 00138 break; 00139 case 'm': # ISO month 00140 if ( is_null($bits['m']) ) { 00141 $m = $this->makeIsoMonth( $bits['F'] ); 00142 if ( !$m || $m == '00' ) { 00143 $fail = true; 00144 } else { 00145 $text .= $m; 00146 } 00147 } else { 00148 $text .= $bits['m']; 00149 } 00150 break; 00151 case 'y': # ISO year 00152 if ( is_null( $bits['y'] ) ) { 00153 $text .= $this->makeIsoYear( $bits['Y'] ); 00154 } else { 00155 $text .= $bits['y']; 00156 } 00157 break; 00158 case 'j': # ordinary day of month 00159 if ( is_null($bits['j']) ) { 00160 $text .= IntVal( $bits['d'] ); 00161 } else { 00162 $text .= $bits['j']; 00163 } 00164 break; 00165 case 'F': # long month 00166 if ( is_null( $bits['F'] ) ) { 00167 $m = IntVal($bits['m']); 00168 if ( $m > 12 || $m < 1 ) { 00169 $fail = true; 00170 } else { 00171 $text .= $wgMonthNamesEn[$m-1]; 00172 } 00173 } else { 00174 $text .= ucfirst( $bits['F'] ); 00175 } 00176 break; 00177 case 'Y': # ordinary (optional BC) year 00178 if ( is_null( $bits['Y'] ) ) { 00179 $text .= $this->makeNormalYear( $bits['y'] ); 00180 } else { 00181 $text .= $bits['Y']; 00182 } 00183 break; 00184 default: 00185 $text .= $char; 00186 } 00187 } 00188 if ( $fail ) { 00189 $text = $matches[0]; 00190 } 00191 return $text; 00192 } 00193 00194 function getMonthRegex() 00195 { 00196 global $wgMonthNamesEn; 00197 return implode( '|', $wgMonthNamesEn ); 00198 } 00199 00200 # Makes an ISO month, e.g. 02, from a month name 00201 function makeIsoMonth( $monthName ) 00202 { 00203 $n = $this->xMonths[strtolower( $monthName )]; 00204 return sprintf( '%02d', $n ); 00205 } 00206 00207 function makeIsoYear( $year ) 00208 { 00209 # Assumes the year is in a nice format, as enforced by the regex 00210 if ( substr( $year, -2 ) == 'BC' ) { 00211 $num = IntVal(substr( $year, 0, -3 )) - 1; 00212 # PHP bug note: sprintf( "%04d", -1 ) fails poorly 00213 $text = sprintf( '-%04d', $num ); 00214 00215 } else { 00216 $text = sprintf( '%04d', $year ); 00217 } 00218 return $text; 00219 } 00220 00221 function makeNormalYear( $iso ) 00222 { 00223 if ( $iso{0} == '-' ) { 00224 $text = (IntVal( substr( $iso, 1 ) ) - 1) . ' BC'; 00225 } else { 00226 $text = IntVal( $iso ); 00227 } 00228 return $text; 00229 } 00230 } 00231 00232 function wfMainDateReplace( $matches ) 00233 { 00234 global $wgDateFormatter; 00235 return $wgDateFormatter->replace( $matches ); 00236 } 00237 ?>

Generated on Tue Jun 29 23:40:03 2004 for Mediawiki by doxygen 1.3.7