127 $monthRegexParts = [];
128 for ( $i = 1; $i <= 12; $i++ ) {
129 $monthName =
$lang->getMonthName( $i );
130 $monthAbbrev =
$lang->getMonthAbbreviation( $i );
131 $this->monthNames[$i] = $monthName;
132 $monthRegexParts[] = preg_quote( $monthName,
'/' );
133 $monthRegexParts[] = preg_quote( $monthAbbrev,
'/' );
134 $this->xMonths[mb_strtolower( $monthName )] = $i;
135 $this->xMonths[mb_strtolower( $monthAbbrev )] = $i;
139 $monthNames = implode(
'|', $monthRegexParts );
140 $dm =
"(?<day>\d{1,2})[ _](?<monthName>{$monthNames})";
141 $md =
"(?<monthName>{$monthNames})[ _](?<day>\d{1,2})";
142 $y =
'(?<year>\d{1,4}([ _]BC|))';
143 $iso =
'(?<isoYear>-?\d{4})-(?<isoMonth>\d{2})-(?<isoDay>\d{2})';
146 self::DMY =>
"/^{$dm}(?: *, *| +){$y}$/iu",
147 self::YDM =>
"/^{$y}(?: *, *| +){$dm}$/iu",
148 self::MDY =>
"/^{$md}(?: *, *| +){$y}$/iu",
149 self::YMD =>
"/^{$y}(?: *, *| +){$md}$/iu",
150 self::DM =>
"/^{$dm}$/iu",
151 self::MD =>
"/^{$md}$/iu",
152 self::ISO =>
"/^{$iso}$/iu",
179 public function reformat( $preference, $text, $options = [] ) {
180 $userFormatId = self::PREFERENCE_IDS[$preference] ?? self::NONE;
181 foreach ( self::TARGET_FORMATS as
$source => $_ ) {
182 if ( isset( self::RULES[$userFormatId][
$source] ) ) {
184 $target = self::RULES[$userFormatId][
$source];
185 } elseif ( isset( self::RULES[self::ALL][
$source] ) ) {
187 $target = self::RULES[self::ALL][
$source];
188 } elseif ( $userFormatId ) {
190 $target = $userFormatId;
195 $format = self::TARGET_FORMATS[$target];
196 $regex = $this->regexes[
$source];
198 $text = preg_replace_callback( $regex,
199 function ( $match ) use ( $format ) {
203 if ( !isset( $match[
'isoYear'] ) && isset( $match[
'year'] ) ) {
204 $match[
'isoYear'] = $this->makeIsoYear( $match[
'year'] );
206 if ( !isset( $match[
'year'] ) && isset( $match[
'isoYear'] ) ) {
207 $match[
'year'] = $this->makeNormalYear( $match[
'isoYear'] );
210 if ( !isset( $match[
'isoMonth'] ) ) {
211 $m = $this->makeIsoMonth( $match[
'monthName'] );
216 $match[
'isoMonth'] = $m;
219 if ( !isset( $match[
'isoDay'] ) ) {
220 $match[
'isoDay'] = sprintf(
'%02d', $match[
'day'] );
223 $formatLength = strlen( $format );
224 for ( $p = 0; $p < $formatLength; $p++ ) {
228 $text .= $match[
'isoDay'];
231 $text .= $match[
'isoMonth'];
235 $text .= $match[
'isoYear'];
238 if ( !isset( $match[
'day'] ) ) {
239 $text .= intval( $match[
'isoDay'] );
241 $text .= $match[
'day'];
245 $m = intval( $match[
'isoMonth'] );
246 if ( $m > 12 || $m < 1 ) {
250 $text .= $this->monthNames[$m];
254 $text .= $match[
'year'];
262 if ( isset( $match[
'isoYear'] ) ) {
263 $isoBits[] = $match[
'isoYear'];
265 $isoBits[] = $match[
'isoMonth'];
266 $isoBits[] = $match[
'isoDay'];
267 $isoDate = implode(
'-', $isoBits );
270 return Html::rawElement(
'span',
271 [
'class' =>
'mw-formatted-date',
'title' => $isoDate ], $text );