1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\Intl\DateFormatter\DateFormat; 13 14/** 15 * Parser and formatter for month format. 16 * 17 * @author Igor Wiedler <igor@wiedler.ch> 18 * 19 * @internal 20 */ 21class MonthTransformer extends Transformer 22{ 23 protected static $months = [ 24 'January', 25 'February', 26 'March', 27 'April', 28 'May', 29 'June', 30 'July', 31 'August', 32 'September', 33 'October', 34 'November', 35 'December', 36 ]; 37 38 /** 39 * Short months names (first 3 letters). 40 */ 41 protected static $shortMonths = []; 42 43 /** 44 * Flipped $months array, $name => $index. 45 */ 46 protected static $flippedMonths = []; 47 48 /** 49 * Flipped $shortMonths array, $name => $index. 50 */ 51 protected static $flippedShortMonths = []; 52 53 public function __construct() 54 { 55 if (0 === \count(self::$shortMonths)) { 56 self::$shortMonths = array_map(function ($month) { 57 return substr($month, 0, 3); 58 }, self::$months); 59 60 self::$flippedMonths = array_flip(self::$months); 61 self::$flippedShortMonths = array_flip(self::$shortMonths); 62 } 63 } 64 65 /** 66 * {@inheritdoc} 67 */ 68 public function format(\DateTime $dateTime, $length) 69 { 70 $matchLengthMap = [ 71 1 => 'n', 72 2 => 'm', 73 3 => 'M', 74 4 => 'F', 75 ]; 76 77 if (isset($matchLengthMap[$length])) { 78 return $dateTime->format($matchLengthMap[$length]); 79 } 80 81 if (5 === $length) { 82 return substr($dateTime->format('M'), 0, 1); 83 } 84 85 return $this->padLeft($dateTime->format('m'), $length); 86 } 87 88 /** 89 * {@inheritdoc} 90 */ 91 public function getReverseMatchingRegExp($length) 92 { 93 switch ($length) { 94 case 1: 95 $regExp = '\d{1,2}'; 96 break; 97 case 3: 98 $regExp = implode('|', self::$shortMonths); 99 break; 100 case 4: 101 $regExp = implode('|', self::$months); 102 break; 103 case 5: 104 $regExp = '[JFMASOND]'; 105 break; 106 default: 107 $regExp = '\d{1,'.$length.'}'; 108 break; 109 } 110 111 return $regExp; 112 } 113 114 /** 115 * {@inheritdoc} 116 */ 117 public function extractDateOptions($matched, $length) 118 { 119 if (!is_numeric($matched)) { 120 if (3 === $length) { 121 $matched = self::$flippedShortMonths[$matched] + 1; 122 } elseif (4 === $length) { 123 $matched = self::$flippedMonths[$matched] + 1; 124 } elseif (5 === $length) { 125 // IntlDateFormatter::parse() always returns false for MMMMM or LLLLL 126 $matched = false; 127 } 128 } else { 129 $matched = (int) $matched; 130 } 131 132 return [ 133 'month' => $matched, 134 ]; 135 } 136} 137