130 $monthRegexParts = [];
131 for ( $i = 1; $i <= 12; $i++ ) {
134 $this->monthNames[$i] = $monthName;
135 $monthRegexParts[] = preg_quote( $monthName,
'/' );
136 $monthRegexParts[] = preg_quote( $monthAbbrev,
'/' );
137 $this->xMonths[mb_strtolower( $monthName )] = $i;
138 $this->xMonths[mb_strtolower( $monthAbbrev )] = $i;
142 $monthNames = implode(
'|', $monthRegexParts );
143 $dm =
"(?<day>\d{1,2})[ _](?<monthName>{$monthNames})";
144 $md =
"(?<monthName>{$monthNames})[ _](?<day>\d{1,2})";
145 $y =
'(?<year>\d{1,4}([ _]BC|))';
146 $iso =
'(?<isoYear>-?\d{4})-(?<isoMonth>\d{2})-(?<isoDay>\d{2})';
149 self::DMY =>
"/^{$dm}(?: *, *| +){$y}$/iu",
150 self::YDM =>
"/^{$y}(?: *, *| +){$dm}$/iu",
151 self::MDY =>
"/^{$md}(?: *, *| +){$y}$/iu",
152 self::YMD =>
"/^{$y}(?: *, *| +){$md}$/iu",
153 self::DM =>
"/^{$dm}$/iu",
154 self::MD =>
"/^{$md}$/iu",
155 self::ISO =>
"/^{$iso}$/iu",
182 public function reformat( $preference, $text, $options = [] ) {
183 $userFormatId = self::PREFERENCE_IDS[$preference] ?? self::NONE;
184 foreach ( self::TARGET_FORMATS as
$source => $_ ) {
185 if ( isset( self::RULES[$userFormatId][
$source] ) ) {
187 $target = self::RULES[$userFormatId][
$source];
188 } elseif ( isset( self::RULES[self::ALL][
$source] ) ) {
190 $target = self::RULES[self::ALL][
$source];
191 } elseif ( $userFormatId ) {
193 $target = $userFormatId;
198 $format = self::TARGET_FORMATS[$target];
199 $regex = $this->regexes[
$source];
201 $text = preg_replace_callback( $regex,
202 function ( $match ) use ( $format ) {
206 if ( !isset( $match[
'isoYear'] ) && isset( $match[
'year'] ) ) {
207 $match[
'isoYear'] = $this->makeIsoYear( $match[
'year'] );
209 if ( !isset( $match[
'year'] ) && isset( $match[
'isoYear'] ) ) {
210 $match[
'year'] = $this->makeNormalYear( $match[
'isoYear'] );
213 if ( !isset( $match[
'isoMonth'] ) ) {
214 $m = $this->makeIsoMonth( $match[
'monthName'] );
219 $match[
'isoMonth'] = $m;
222 if ( !isset( $match[
'isoDay'] ) ) {
223 $match[
'isoDay'] = sprintf(
'%02d', $match[
'day'] );
226 $formatLength = strlen( $format );
227 for ( $p = 0; $p < $formatLength; $p++ ) {
231 $text .= $match[
'isoDay'];
234 $text .= $match[
'isoMonth'];
238 $text .= $match[
'isoYear'];
241 if ( !isset( $match[
'day'] ) ) {
242 $text .= intval( $match[
'isoDay'] );
244 $text .= $match[
'day'];
248 $m = intval( $match[
'isoMonth'] );
249 if ( $m > 12 || $m < 1 ) {
253 $text .= $this->monthNames[$m];
257 $text .= $match[
'year'];
265 if ( isset( $match[
'isoYear'] ) ) {
266 $isoBits[] = $match[
'isoYear'];
268 $isoBits[] = $match[
'isoMonth'];
269 $isoBits[] = $match[
'isoDay'];
270 $isoDate = implode(
'-', $isoBits );
273 return Html::rawElement(
'span',
274 [
'class' =>
'mw-formatted-date',
'title' => $isoDate ], $text );