116 $monthRegexParts = [];
117 for ( $i = 1; $i <= 12; $i++ ) {
120 $this->monthNames[$i] = $monthName;
121 $monthRegexParts[] = preg_quote( $monthName,
'/' );
122 $monthRegexParts[] = preg_quote( $monthAbbrev,
'/' );
123 $this->xMonths[mb_strtolower( $monthName )] = $i;
124 $this->xMonths[mb_strtolower( $monthAbbrev )] = $i;
128 $monthNames = implode(
'|', $monthRegexParts );
129 $dm =
"(?<day>\d{1,2})[ _](?<monthName>{$monthNames})";
130 $md =
"(?<monthName>{$monthNames})[ _](?<day>\d{1,2})";
131 $y =
'(?<year>\d{1,4}([ _]BC|))';
132 $iso =
'(?<isoYear>-?\d{4})-(?<isoMonth>\d{2})-(?<isoDay>\d{2})';
135 self::DMY =>
"/^{$dm}(?: *, *| +){$y}$/iu",
136 self::YDM =>
"/^{$y}(?: *, *| +){$dm}$/iu",
137 self::MDY =>
"/^{$md}(?: *, *| +){$y}$/iu",
138 self::YMD =>
"/^{$y}(?: *, *| +){$md}$/iu",
139 self::DM =>
"/^{$dm}$/iu",
140 self::MD =>
"/^{$md}$/iu",
141 self::ISO =>
"/^{$iso}$/iu",
168 public function reformat( $preference, $text, $options = [] ) {
169 $userFormatId = self::PREFERENCE_IDS[$preference] ?? self::NONE;
170 foreach ( self::TARGET_FORMATS as
$source => $_ ) {
171 if ( isset( self::RULES[$userFormatId][
$source] ) ) {
173 $target = self::RULES[$userFormatId][
$source];
174 } elseif ( isset( self::RULES[self::ALL][
$source] ) ) {
176 $target = self::RULES[self::ALL][
$source];
177 } elseif ( $userFormatId ) {
179 $target = $userFormatId;
184 $format = self::TARGET_FORMATS[$target];
185 $regex = $this->regexes[
$source];
187 $text = preg_replace_callback( $regex,
188 function ( $match ) use ( $format ) {
192 if ( !isset( $match[
'isoYear'] ) && isset( $match[
'year'] ) ) {
193 $match[
'isoYear'] = $this->makeIsoYear( $match[
'year'] );
195 if ( !isset( $match[
'year'] ) && isset( $match[
'isoYear'] ) ) {
196 $match[
'year'] = $this->makeNormalYear( $match[
'isoYear'] );
199 if ( !isset( $match[
'isoMonth'] ) ) {
200 $m = $this->makeIsoMonth( $match[
'monthName'] );
205 $match[
'isoMonth'] = $m;
208 if ( !isset( $match[
'isoDay'] ) ) {
209 $match[
'isoDay'] = sprintf(
'%02d', $match[
'day'] );
212 $formatLength = strlen( $format );
213 for ( $p = 0; $p < $formatLength; $p++ ) {
217 $text .= $match[
'isoDay'];
220 $text .= $match[
'isoMonth'];
223 $text .= $match[
'isoYear'];
226 if ( !isset( $match[
'day'] ) ) {
227 $text .= intval( $match[
'isoDay'] );
229 $text .= $match[
'day'];
233 $m = intval( $match[
'isoMonth'] );
234 if ( $m > 12 || $m < 1 ) {
238 $text .= $this->monthNames[$m];
242 $text .= $match[
'year'];
250 if ( isset( $match[
'isoYear'] ) ) {
251 $isoBits[] = $match[
'isoYear'];
253 $isoBits[] = $match[
'isoMonth'];
254 $isoBits[] = $match[
'isoDay'];
255 $isoDate = implode(
'-', $isoBits );
258 return Html::rawElement(
'span',
259 [
'class' =>
'mw-formatted-date',
'title' => $isoDate ], $text );