StubIntlDateFormatter.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Locale\Stub;
  11. use Symfony\Component\Locale\Exception\MethodNotImplementedException;
  12. use Symfony\Component\Locale\Exception\MethodArgumentValueNotImplementedException;
  13. /**
  14. * Provides a stub IntlDateFormatter for the 'en' locale.
  15. */
  16. class StubIntlDateFormatter
  17. {
  18. /* formats */
  19. const NONE = -1;
  20. const FULL = 0;
  21. const LONG = 1;
  22. const MEDIUM = 2;
  23. const SHORT = 3;
  24. /* formats */
  25. const TRADITIONAL = 0;
  26. const GREGORIAN = 1;
  27. private $defaultDateFormats = array(
  28. self::NONE => '',
  29. self::FULL => 'EEEE, LLLL d, y',
  30. self::LONG => 'LLLL d, y',
  31. self::MEDIUM => 'LLL d, y',
  32. self::SHORT => 'M/d/yy',
  33. );
  34. private $defaultTimeFormats = array(
  35. self::FULL => 'h:mm:ss a zzzz',
  36. self::LONG => 'h:mm:ss a z',
  37. self::MEDIUM => 'h:mm:ss a',
  38. self::SHORT => 'h:mm a',
  39. );
  40. private $datetype;
  41. private $timetype;
  42. private $pattern;
  43. private $dateTimeZone;
  44. public function __construct($locale, $datetype, $timetype, $timezone = null, $calendar = null, $pattern = null)
  45. {
  46. if ('en' != $locale) {
  47. throw new MethodArgumentValueNotImplementedException(__METHOD__, 'locale', $locale, 'Only the \'en\' locale is supported');
  48. }
  49. $this->datetype = $datetype;
  50. $this->timetype = $timetype;
  51. $this->setPattern($pattern);
  52. $this->setTimeZoneId($timezone);
  53. }
  54. public function format($timestamp)
  55. {
  56. $dateTime = new \DateTime();
  57. $dateTime->setTimestamp($timestamp);
  58. $dateTime->setTimezone($this->dateTimeZone);
  59. // not implemented: YuwWFgecSAZvVW
  60. $specialChars = 'MLydGQqhDEaHkKmsz';
  61. $specialCharsArray = str_split($specialChars);
  62. $specialCharsMatch = implode('|', array_map(function($char) {
  63. return $char . '+';
  64. }, $specialCharsArray));
  65. $quoteMatch = "'(?:[^']+|'')*'";
  66. $regExp = "/($quoteMatch|$specialCharsMatch)/";
  67. $callback = function($matches) use ($dateTime) {
  68. $datePattern = $matches[0];
  69. $length = strlen($datePattern);
  70. if ("'" === $datePattern[0]) {
  71. if (preg_match("/^'+$/", $datePattern)) {
  72. return str_replace("''", "'", $datePattern);
  73. }
  74. return str_replace("''", "'", substr($datePattern, 1, -1));
  75. }
  76. switch ($datePattern[0]) {
  77. case 'M':
  78. case 'L':
  79. $matchLengthMap = array(
  80. 1 => 'n',
  81. 2 => 'm',
  82. 3 => 'M',
  83. 4 => 'F',
  84. );
  85. if (isset($matchLengthMap[$length])) {
  86. return $dateTime->format($matchLengthMap[$length]);
  87. } else if (5 == $length) {
  88. return substr($dateTime->format('M'), 0, 1);
  89. } else {
  90. return str_pad($dateTime->format('m'), $length, '0', STR_PAD_LEFT);
  91. }
  92. break;
  93. case 'y':
  94. $matchLengthMap = array(
  95. 1 => 'Y',
  96. 2 => 'y',
  97. 3 => 'Y',
  98. 4 => 'Y',
  99. );
  100. if (isset($matchLengthMap[$length])) {
  101. return $dateTime->format($matchLengthMap[$length]);
  102. } else {
  103. return str_pad($dateTime->format('Y'), $length, '0', STR_PAD_LEFT);
  104. }
  105. break;
  106. case 'd':
  107. return str_pad($dateTime->format('j'), $length, '0', STR_PAD_LEFT);
  108. break;
  109. case 'G':
  110. $year = (int) $dateTime->format('Y');
  111. return $year >= 0 ? 'AD' : 'BC';
  112. break;
  113. case 'q':
  114. case 'Q':
  115. $month = (int) $dateTime->format('n');
  116. $quarter = (int) floor(($month - 1) / 3) + 1;
  117. switch ($length) {
  118. case 1:
  119. case 2:
  120. return str_pad($quarter, $length, '0', STR_PAD_LEFT);
  121. break;
  122. case 3:
  123. return 'Q' . $quarter;
  124. break;
  125. default:
  126. $map = array(1 => '1st quarter', 2 => '2nd quarter', 3 => '3rd quarter', 4 => '4th quarter');
  127. return $map[$quarter];
  128. break;
  129. }
  130. break;
  131. case 'h':
  132. return str_pad($dateTime->format('g'), $length, '0', STR_PAD_LEFT);
  133. break;
  134. case 'D':
  135. $dayOfYear = $dateTime->format('z') + 1;
  136. return str_pad($dayOfYear, $length, '0', STR_PAD_LEFT);
  137. break;
  138. case 'E':
  139. $dayOfWeek = $dateTime->format('l');
  140. switch ($length) {
  141. case 4:
  142. return $dayOfWeek;
  143. break;
  144. case 5:
  145. return $dayOfWeek[0];
  146. break;
  147. default:
  148. return substr($dayOfWeek, 0, 3);
  149. }
  150. break;
  151. case 'a':
  152. return $dateTime->format('A');
  153. break;
  154. case 'H':
  155. return str_pad($dateTime->format('G'), $length, '0', STR_PAD_LEFT);
  156. break;
  157. case 'k':
  158. $hourOfDay = $dateTime->format('G');
  159. $hourOfDay = ('0' == $hourOfDay) ? '24' : $hourOfDay;
  160. return str_pad($hourOfDay, $length, '0', STR_PAD_LEFT);
  161. break;
  162. case 'K':
  163. $hourOfDay = $dateTime->format('g');
  164. $hourOfDay = ('12' == $hourOfDay) ? '0' : $hourOfDay;
  165. return str_pad($hourOfDay, $length, '0', STR_PAD_LEFT);
  166. break;
  167. case 'm':
  168. $minuteOfHour = (int) $dateTime->format('i');
  169. return str_pad($minuteOfHour, $length, '0', STR_PAD_LEFT);
  170. break;
  171. case 's':
  172. $secondOfMinute = (int) $dateTime->format('s');
  173. return str_pad($secondOfMinute, $length, '0', STR_PAD_LEFT);
  174. break;
  175. case 'z':
  176. return $dateTime->format('\G\M\TP');
  177. break;
  178. }
  179. };
  180. $formatted = preg_replace_callback($regExp, $callback, $this->getPattern());
  181. return $formatted;
  182. }
  183. public function getCalendar()
  184. {
  185. return self::GREGORIAN;
  186. }
  187. public function getDateType()
  188. {
  189. return $this->datetype;
  190. }
  191. public function setLocale($locale)
  192. {
  193. throw new MethodNotImplementedException(__METHOD__);
  194. }
  195. public function getErrorCode()
  196. {
  197. throw new MethodNotImplementedException(__METHOD__);
  198. }
  199. public function getErrorMessage()
  200. {
  201. throw new MethodNotImplementedException(__METHOD__);
  202. }
  203. public function getLocale()
  204. {
  205. return 'en';
  206. }
  207. public function getPattern()
  208. {
  209. return $this->pattern;
  210. }
  211. public function getTimeType()
  212. {
  213. return $this->timetype;
  214. }
  215. public function getTimeZoneId()
  216. {
  217. return $this->dateTimeZone->getName();
  218. }
  219. public function isLenient()
  220. {
  221. throw new MethodNotImplementedException(__METHOD__);
  222. }
  223. public function localtime($value, &$position = 0)
  224. {
  225. throw new MethodNotImplementedException(__METHOD__);
  226. }
  227. public function parse($value, &$position = 0)
  228. {
  229. throw new MethodNotImplementedException(__METHOD__);
  230. }
  231. public function setCalendar()
  232. {
  233. throw new MethodNotImplementedException(__METHOD__);
  234. }
  235. public function setLenient($lenient)
  236. {
  237. throw new MethodNotImplementedException(__METHOD__);
  238. }
  239. public function setPattern($pattern)
  240. {
  241. if (null === $pattern) {
  242. $patternParts = array();
  243. if (self::NONE !== $this->datetype) {
  244. $patternParts[] = $this->defaultDateFormats[$this->datetype];
  245. }
  246. if (self::NONE !== $this->timetype) {
  247. $patternParts[] = $this->defaultTimeFormats[$this->timetype];
  248. }
  249. $pattern = implode(' ', $patternParts);
  250. }
  251. $this->pattern = $pattern;
  252. }
  253. public function setTimeZoneId($timeZoneId)
  254. {
  255. try {
  256. $this->dateTimeZone = new \DateTimeZone($timeZoneId);
  257. } catch (\Exception $e) {
  258. $this->dateTimeZone = new \DateTimeZone('UTC');
  259. }
  260. }
  261. static public function create($locale, $datetype, $timetype, $timezone = null, $calendar = null, $pattern = null)
  262. {
  263. return new self($locale, $datetype, $timetype, $timezone, $calendar, $pattern);
  264. }
  265. }