BaseFormatConverter.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\helpers;
  8. use IntlDateFormatter;
  9. use Yii;
  10. /**
  11. * BaseFormatConverter provides concrete implementation for [[FormatConverter]].
  12. *
  13. * Do not use BaseFormatConverter. Use [[FormatConverter]] instead.
  14. *
  15. * @author Carsten Brandt <mail@cebe.cc>
  16. * @author Enrica Ruedin <e.ruedin@guggach.com>
  17. * @since 2.0
  18. */
  19. class BaseFormatConverter
  20. {
  21. /**
  22. * @var array the php fallback definition to use for the ICU short patterns `short`, `medium`, `long` and `full`.
  23. * This is used as fallback when the intl extension is not installed.
  24. */
  25. public static $phpFallbackDatePatterns = [
  26. 'short' => [
  27. 'date' => 'n/j/y',
  28. 'time' => 'H:i',
  29. 'datetime' => 'n/j/y H:i',
  30. ],
  31. 'medium' => [
  32. 'date' => 'M j, Y',
  33. 'time' => 'g:i:s A',
  34. 'datetime' => 'M j, Y g:i:s A',
  35. ],
  36. 'long' => [
  37. 'date' => 'F j, Y',
  38. 'time' => 'g:i:sA',
  39. 'datetime' => 'F j, Y g:i:sA',
  40. ],
  41. 'full' => [
  42. 'date' => 'l, F j, Y',
  43. 'time' => 'g:i:sA T',
  44. 'datetime' => 'l, F j, Y g:i:sA T',
  45. ],
  46. ];
  47. /**
  48. * @var array the jQuery UI fallback definition to use for the ICU short patterns `short`, `medium`, `long` and `full`.
  49. * This is used as fallback when the intl extension is not installed.
  50. */
  51. public static $juiFallbackDatePatterns = [
  52. 'short' => [
  53. 'date' => 'd/m/y',
  54. 'time' => '',
  55. 'datetime' => 'd/m/y',
  56. ],
  57. 'medium' => [
  58. 'date' => 'M d, yy',
  59. 'time' => '',
  60. 'datetime' => 'M d, yy',
  61. ],
  62. 'long' => [
  63. 'date' => 'MM d, yy',
  64. 'time' => '',
  65. 'datetime' => 'MM d, yy',
  66. ],
  67. 'full' => [
  68. 'date' => 'DD, MM d, yy',
  69. 'time' => '',
  70. 'datetime' => 'DD, MM d, yy',
  71. ],
  72. ];
  73. private static $_icuShortFormats = [
  74. 'short' => 3, // IntlDateFormatter::SHORT,
  75. 'medium' => 2, // IntlDateFormatter::MEDIUM,
  76. 'long' => 1, // IntlDateFormatter::LONG,
  77. 'full' => 0, // IntlDateFormatter::FULL,
  78. ];
  79. /**
  80. * Converts a date format pattern from [ICU format][] to [php date() function format][].
  81. *
  82. * The conversion is limited to date patterns that do not use escaped characters.
  83. * Patterns like `d 'of' MMMM yyyy` which will result in a date like `1 of December 2014` may not be converted correctly
  84. * because of the use of escaped characters.
  85. *
  86. * Pattern constructs that are not supported by the PHP format will be removed.
  87. *
  88. * [php date() function format]: https://secure.php.net/manual/en/function.date.php
  89. * [ICU format]: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax
  90. *
  91. * @param string $pattern date format pattern in ICU format.
  92. * @param string $type 'date', 'time', or 'datetime'.
  93. * @param string $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`.
  94. * If not given, `Yii::$app->language` will be used.
  95. * @return string The converted date format pattern.
  96. */
  97. public static function convertDateIcuToPhp($pattern, $type = 'date', $locale = null)
  98. {
  99. if (isset(self::$_icuShortFormats[$pattern])) {
  100. if (extension_loaded('intl')) {
  101. if ($locale === null) {
  102. $locale = Yii::$app->language;
  103. }
  104. if ($type === 'date') {
  105. $formatter = new IntlDateFormatter($locale, self::$_icuShortFormats[$pattern], IntlDateFormatter::NONE);
  106. } elseif ($type === 'time') {
  107. $formatter = new IntlDateFormatter($locale, IntlDateFormatter::NONE, self::$_icuShortFormats[$pattern]);
  108. } else {
  109. $formatter = new IntlDateFormatter($locale, self::$_icuShortFormats[$pattern], self::$_icuShortFormats[$pattern]);
  110. }
  111. $pattern = $formatter->getPattern();
  112. } else {
  113. return static::$phpFallbackDatePatterns[$pattern][$type];
  114. }
  115. }
  116. // http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax
  117. // escaped text
  118. $escaped = [];
  119. if (preg_match_all('/(?<!\')\'(.*?[^\'])\'(?!\')/', $pattern, $matches, PREG_SET_ORDER)) {
  120. foreach ($matches as $match) {
  121. $match[1] = str_replace('\'\'', '\'', $match[1]);
  122. $escaped[$match[0]] = '\\' . implode('\\', preg_split('//u', $match[1], -1, PREG_SPLIT_NO_EMPTY));
  123. }
  124. }
  125. return strtr($pattern, array_merge($escaped, [
  126. "''" => "\\'", // two single quotes produce one
  127. 'G' => '', // era designator like (Anno Domini)
  128. 'Y' => 'o', // 4digit year of "Week of Year"
  129. 'y' => 'Y', // 4digit year e.g. 2014
  130. 'yyyy' => 'Y', // 4digit year e.g. 2014
  131. 'yy' => 'y', // 2digit year number eg. 14
  132. 'u' => '', // extended year e.g. 4601
  133. 'U' => '', // cyclic year name, as in Chinese lunar calendar
  134. 'r' => '', // related Gregorian year e.g. 1996
  135. 'Q' => '', // number of quarter
  136. 'QQ' => '', // number of quarter '02'
  137. 'QQQ' => '', // quarter 'Q2'
  138. 'QQQQ' => '', // quarter '2nd quarter'
  139. 'QQQQQ' => '', // number of quarter '2'
  140. 'q' => '', // number of Stand Alone quarter
  141. 'qq' => '', // number of Stand Alone quarter '02'
  142. 'qqq' => '', // Stand Alone quarter 'Q2'
  143. 'qqqq' => '', // Stand Alone quarter '2nd quarter'
  144. 'qqqqq' => '', // number of Stand Alone quarter '2'
  145. 'M' => 'n', // Numeric representation of a month, without leading zeros
  146. 'MM' => 'm', // Numeric representation of a month, with leading zeros
  147. 'MMM' => 'M', // A short textual representation of a month, three letters
  148. 'MMMM' => 'F', // A full textual representation of a month, such as January or March
  149. 'MMMMM' => '',
  150. 'L' => 'n', // Stand alone month in year
  151. 'LL' => 'm', // Stand alone month in year
  152. 'LLL' => 'M', // Stand alone month in year
  153. 'LLLL' => 'F', // Stand alone month in year
  154. 'LLLLL' => '', // Stand alone month in year
  155. 'w' => 'W', // ISO-8601 week number of year
  156. 'ww' => 'W', // ISO-8601 week number of year
  157. 'W' => '', // week of the current month
  158. 'd' => 'j', // day without leading zeros
  159. 'dd' => 'd', // day with leading zeros
  160. 'D' => 'z', // day of the year 0 to 365
  161. 'F' => '', // Day of Week in Month. eg. 2nd Wednesday in July
  162. 'g' => '', // Modified Julian day. This is different from the conventional Julian day number in two regards.
  163. 'E' => 'D', // day of week written in short form eg. Sun
  164. 'EE' => 'D',
  165. 'EEE' => 'D',
  166. 'EEEE' => 'l', // day of week fully written eg. Sunday
  167. 'EEEEE' => '',
  168. 'EEEEEE' => '',
  169. 'e' => 'N', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
  170. 'ee' => 'N', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
  171. 'eee' => 'D',
  172. 'eeee' => 'l',
  173. 'eeeee' => '',
  174. 'eeeeee' => '',
  175. 'c' => 'N', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
  176. 'cc' => 'N', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
  177. 'ccc' => 'D',
  178. 'cccc' => 'l',
  179. 'ccccc' => '',
  180. 'cccccc' => '',
  181. 'a' => 'A', // AM/PM marker
  182. 'h' => 'g', // 12-hour format of an hour without leading zeros 1 to 12h
  183. 'hh' => 'h', // 12-hour format of an hour with leading zeros, 01 to 12 h
  184. 'H' => 'G', // 24-hour format of an hour without leading zeros 0 to 23h
  185. 'HH' => 'H', // 24-hour format of an hour with leading zeros, 00 to 23 h
  186. 'k' => '', // hour in day (1~24)
  187. 'kk' => '', // hour in day (1~24)
  188. 'K' => '', // hour in am/pm (0~11)
  189. 'KK' => '', // hour in am/pm (0~11)
  190. 'm' => 'i', // Minutes without leading zeros, not supported by php but we fallback
  191. 'mm' => 'i', // Minutes with leading zeros
  192. 's' => 's', // Seconds, without leading zeros, not supported by php but we fallback
  193. 'ss' => 's', // Seconds, with leading zeros
  194. 'S' => '', // fractional second
  195. 'SS' => '', // fractional second
  196. 'SSS' => '', // fractional second
  197. 'SSSS' => '', // fractional second
  198. 'A' => '', // milliseconds in day
  199. 'z' => 'T', // Timezone abbreviation
  200. 'zz' => 'T', // Timezone abbreviation
  201. 'zzz' => 'T', // Timezone abbreviation
  202. 'zzzz' => 'T', // Timezone full name, not supported by php but we fallback
  203. 'Z' => 'O', // Difference to Greenwich time (GMT) in hours
  204. 'ZZ' => 'O', // Difference to Greenwich time (GMT) in hours
  205. 'ZZZ' => 'O', // Difference to Greenwich time (GMT) in hours
  206. 'ZZZZ' => '\G\M\TP', // Time Zone: long localized GMT (=OOOO) e.g. GMT-08:00
  207. 'ZZZZZ' => '', // TIme Zone: ISO8601 extended hms? (=XXXXX)
  208. 'O' => '', // Time Zone: short localized GMT e.g. GMT-8
  209. 'OOOO' => '\G\M\TP', // Time Zone: long localized GMT (=ZZZZ) e.g. GMT-08:00
  210. 'v' => '\G\M\TP', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
  211. 'vvvv' => '\G\M\TP', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
  212. 'V' => '', // Time Zone: short time zone ID
  213. 'VV' => 'e', // Time Zone: long time zone ID
  214. 'VVV' => '', // Time Zone: time zone exemplar city
  215. 'VVVV' => '\G\M\TP', // Time Zone: generic location (falls back to OOOO) using the ICU defined fallback here
  216. 'X' => '', // Time Zone: ISO8601 basic hm?, with Z for 0, e.g. -08, +0530, Z
  217. 'XX' => 'O, \Z', // Time Zone: ISO8601 basic hm, with Z, e.g. -0800, Z
  218. 'XXX' => 'P, \Z', // Time Zone: ISO8601 extended hm, with Z, e.g. -08:00, Z
  219. 'XXXX' => '', // Time Zone: ISO8601 basic hms?, with Z, e.g. -0800, -075258, Z
  220. 'XXXXX' => '', // Time Zone: ISO8601 extended hms?, with Z, e.g. -08:00, -07:52:58, Z
  221. 'x' => '', // Time Zone: ISO8601 basic hm?, without Z for 0, e.g. -08, +0530
  222. 'xx' => 'O', // Time Zone: ISO8601 basic hm, without Z, e.g. -0800
  223. 'xxx' => 'P', // Time Zone: ISO8601 extended hm, without Z, e.g. -08:00
  224. 'xxxx' => '', // Time Zone: ISO8601 basic hms?, without Z, e.g. -0800, -075258
  225. 'xxxxx' => '', // Time Zone: ISO8601 extended hms?, without Z, e.g. -08:00, -07:52:58
  226. ]));
  227. }
  228. /**
  229. * Converts a date format pattern from [php date() function format][] to [ICU format][].
  230. *
  231. * Pattern constructs that are not supported by the ICU format will be removed.
  232. *
  233. * [php date() function format]: https://secure.php.net/manual/en/function.date.php
  234. * [ICU format]: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax
  235. *
  236. * Since 2.0.13 it handles escaped characters correctly.
  237. *
  238. * @param string $pattern date format pattern in php date()-function format.
  239. * @return string The converted date format pattern.
  240. */
  241. public static function convertDatePhpToIcu($pattern)
  242. {
  243. // https://secure.php.net/manual/en/function.date.php
  244. $result = strtr($pattern, [
  245. "'" => "''''", // single `'` should be encoded as `''`, which internally should be encoded as `''''`
  246. // Day
  247. '\d' => "'d'",
  248. 'd' => 'dd', // Day of the month, 2 digits with leading zeros 01 to 31
  249. '\D' => "'D'",
  250. 'D' => 'eee', // A textual representation of a day, three letters Mon through Sun
  251. '\j' => "'j'",
  252. 'j' => 'd', // Day of the month without leading zeros 1 to 31
  253. '\l' => "'l'",
  254. 'l' => 'eeee', // A full textual representation of the day of the week Sunday through Saturday
  255. '\N' => "'N'",
  256. 'N' => 'e', // ISO-8601 numeric representation of the day of the week, 1 (for Monday) through 7 (for Sunday)
  257. '\S' => "'S'",
  258. 'S' => '', // English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
  259. '\w' => "'w'",
  260. 'w' => '', // Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
  261. '\z' => "'z'",
  262. 'z' => 'D', // The day of the year (starting from 0) 0 through 365
  263. // Week
  264. '\W' => "'W'",
  265. 'W' => 'w', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) Example: 42 (the 42nd week in the year)
  266. // Month
  267. '\F' => "'F'",
  268. 'F' => 'MMMM', // A full textual representation of a month, January through December
  269. '\m' => "'m'",
  270. 'm' => 'MM', // Numeric representation of a month, with leading zeros 01 through 12
  271. '\M' => "'M'",
  272. 'M' => 'MMM', // A short textual representation of a month, three letters Jan through Dec
  273. '\n' => "'n'",
  274. 'n' => 'M', // Numeric representation of a month, without leading zeros 1 through 12, not supported by ICU but we fallback to "with leading zero"
  275. '\t' => "'t'",
  276. 't' => '', // Number of days in the given month 28 through 31
  277. // Year
  278. '\L' => "'L'",
  279. 'L' => '', // Whether it's a leap year, 1 if it is a leap year, 0 otherwise.
  280. '\o' => "'o'",
  281. 'o' => 'Y', // ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead.
  282. '\Y' => "'Y'",
  283. 'Y' => 'yyyy', // A full numeric representation of a year, 4 digits Examples: 1999 or 2003
  284. '\y' => "'y'",
  285. 'y' => 'yy', // A two digit representation of a year Examples: 99 or 03
  286. // Time
  287. '\a' => "'a'",
  288. 'a' => 'a', // Lowercase Ante meridiem and Post meridiem, am or pm
  289. '\A' => "'A'",
  290. 'A' => 'a', // Uppercase Ante meridiem and Post meridiem, AM or PM, not supported by ICU but we fallback to lowercase
  291. '\B' => "'B'",
  292. 'B' => '', // Swatch Internet time 000 through 999
  293. '\g' => "'g'",
  294. 'g' => 'h', // 12-hour format of an hour without leading zeros 1 through 12
  295. '\G' => "'G'",
  296. 'G' => 'H', // 24-hour format of an hour without leading zeros 0 to 23h
  297. '\h' => "'h'",
  298. 'h' => 'hh', // 12-hour format of an hour with leading zeros, 01 to 12 h
  299. '\H' => "'H'",
  300. 'H' => 'HH', // 24-hour format of an hour with leading zeros, 00 to 23 h
  301. '\i' => "'i'",
  302. 'i' => 'mm', // Minutes with leading zeros 00 to 59
  303. '\s' => "'s'",
  304. 's' => 'ss', // Seconds, with leading zeros 00 through 59
  305. '\u' => "'u'",
  306. 'u' => '', // Microseconds. Example: 654321
  307. // Timezone
  308. '\e' => "'e'",
  309. 'e' => 'VV', // Timezone identifier. Examples: UTC, GMT, Atlantic/Azores
  310. '\I' => "'I'",
  311. 'I' => '', // Whether or not the date is in daylight saving time, 1 if Daylight Saving Time, 0 otherwise.
  312. '\O' => "'O'",
  313. 'O' => 'xx', // Difference to Greenwich time (GMT) in hours, Example: +0200
  314. '\P' => "'P'",
  315. 'P' => 'xxx', // Difference to Greenwich time (GMT) with colon between hours and minutes, Example: +02:00
  316. '\T' => "'T'",
  317. 'T' => 'zzz', // Timezone abbreviation, Examples: EST, MDT ...
  318. '\Z' => "'Z'",
  319. 'Z' => '', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
  320. // Full Date/Time
  321. '\c' => "'c'",
  322. 'c' => "yyyy-MM-dd'T'HH:mm:ssxxx", // ISO 8601 date, e.g. 2004-02-12T15:19:21+00:00
  323. '\r' => "'r'",
  324. 'r' => 'eee, dd MMM yyyy HH:mm:ss xx', // RFC 2822 formatted date, Example: Thu, 21 Dec 2000 16:01:07 +0200
  325. '\U' => "'U'",
  326. 'U' => '', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
  327. '\\\\' => '\\',
  328. ]);
  329. // remove `''` - the're result of consecutive escaped chars (`\A\B` will be `'A''B'`, but should be `'AB'`)
  330. // real `'` are encoded as `''''`
  331. return strtr($result, [
  332. "''''" => "''",
  333. "''" => '',
  334. ]);
  335. }
  336. /**
  337. * Converts a date format pattern from [ICU format][] to [jQuery UI date format][].
  338. *
  339. * Pattern constructs that are not supported by the jQuery UI format will be removed.
  340. *
  341. * [jQuery UI date format]: http://api.jqueryui.com/datepicker/#utility-formatDate
  342. * [ICU format]: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax
  343. *
  344. * @param string $pattern date format pattern in ICU format.
  345. * @param string $type 'date', 'time', or 'datetime'.
  346. * @param string $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`.
  347. * If not given, `Yii::$app->language` will be used.
  348. * @return string The converted date format pattern.
  349. */
  350. public static function convertDateIcuToJui($pattern, $type = 'date', $locale = null)
  351. {
  352. if (isset(self::$_icuShortFormats[$pattern])) {
  353. if (extension_loaded('intl')) {
  354. if ($locale === null) {
  355. $locale = Yii::$app->language;
  356. }
  357. if ($type === 'date') {
  358. $formatter = new IntlDateFormatter($locale, self::$_icuShortFormats[$pattern], IntlDateFormatter::NONE);
  359. } elseif ($type === 'time') {
  360. $formatter = new IntlDateFormatter($locale, IntlDateFormatter::NONE, self::$_icuShortFormats[$pattern]);
  361. } else {
  362. $formatter = new IntlDateFormatter($locale, self::$_icuShortFormats[$pattern], self::$_icuShortFormats[$pattern]);
  363. }
  364. $pattern = $formatter->getPattern();
  365. } else {
  366. return static::$juiFallbackDatePatterns[$pattern][$type];
  367. }
  368. }
  369. // http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax
  370. // escaped text
  371. $escaped = [];
  372. if (preg_match_all('/(?<!\')\'.*?[^\']\'(?!\')/', $pattern, $matches)) {
  373. foreach ($matches[0] as $match) {
  374. $escaped[$match] = $match;
  375. }
  376. }
  377. return strtr($pattern, array_merge($escaped, [
  378. 'G' => '', // era designator like (Anno Domini)
  379. 'Y' => '', // 4digit year of "Week of Year"
  380. 'y' => 'yy', // 4digit year e.g. 2014
  381. 'yyyy' => 'yy', // 4digit year e.g. 2014
  382. 'yy' => 'y', // 2digit year number eg. 14
  383. 'u' => '', // extended year e.g. 4601
  384. 'U' => '', // cyclic year name, as in Chinese lunar calendar
  385. 'r' => '', // related Gregorian year e.g. 1996
  386. 'Q' => '', // number of quarter
  387. 'QQ' => '', // number of quarter '02'
  388. 'QQQ' => '', // quarter 'Q2'
  389. 'QQQQ' => '', // quarter '2nd quarter'
  390. 'QQQQQ' => '', // number of quarter '2'
  391. 'q' => '', // number of Stand Alone quarter
  392. 'qq' => '', // number of Stand Alone quarter '02'
  393. 'qqq' => '', // Stand Alone quarter 'Q2'
  394. 'qqqq' => '', // Stand Alone quarter '2nd quarter'
  395. 'qqqqq' => '', // number of Stand Alone quarter '2'
  396. 'M' => 'm', // Numeric representation of a month, without leading zeros
  397. 'MM' => 'mm', // Numeric representation of a month, with leading zeros
  398. 'MMM' => 'M', // A short textual representation of a month, three letters
  399. 'MMMM' => 'MM', // A full textual representation of a month, such as January or March
  400. 'MMMMM' => '',
  401. 'L' => 'm', // Stand alone month in year
  402. 'LL' => 'mm', // Stand alone month in year
  403. 'LLL' => 'M', // Stand alone month in year
  404. 'LLLL' => 'MM', // Stand alone month in year
  405. 'LLLLL' => '', // Stand alone month in year
  406. 'w' => '', // ISO-8601 week number of year
  407. 'ww' => '', // ISO-8601 week number of year
  408. 'W' => '', // week of the current month
  409. 'd' => 'd', // day without leading zeros
  410. 'dd' => 'dd', // day with leading zeros
  411. 'D' => 'o', // day of the year 0 to 365
  412. 'F' => '', // Day of Week in Month. eg. 2nd Wednesday in July
  413. 'g' => '', // Modified Julian day. This is different from the conventional Julian day number in two regards.
  414. 'E' => 'D', // day of week written in short form eg. Sun
  415. 'EE' => 'D',
  416. 'EEE' => 'D',
  417. 'EEEE' => 'DD', // day of week fully written eg. Sunday
  418. 'EEEEE' => '',
  419. 'EEEEEE' => '',
  420. 'e' => '', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
  421. 'ee' => '', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
  422. 'eee' => 'D',
  423. 'eeee' => '',
  424. 'eeeee' => '',
  425. 'eeeeee' => '',
  426. 'c' => '', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
  427. 'cc' => '', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
  428. 'ccc' => 'D',
  429. 'cccc' => 'DD',
  430. 'ccccc' => '',
  431. 'cccccc' => '',
  432. 'a' => '', // am/pm marker
  433. 'h' => '', // 12-hour format of an hour without leading zeros 1 to 12h
  434. 'hh' => '', // 12-hour format of an hour with leading zeros, 01 to 12 h
  435. 'H' => '', // 24-hour format of an hour without leading zeros 0 to 23h
  436. 'HH' => '', // 24-hour format of an hour with leading zeros, 00 to 23 h
  437. 'k' => '', // hour in day (1~24)
  438. 'kk' => '', // hour in day (1~24)
  439. 'K' => '', // hour in am/pm (0~11)
  440. 'KK' => '', // hour in am/pm (0~11)
  441. 'm' => '', // Minutes without leading zeros, not supported by php but we fallback
  442. 'mm' => '', // Minutes with leading zeros
  443. 's' => '', // Seconds, without leading zeros, not supported by php but we fallback
  444. 'ss' => '', // Seconds, with leading zeros
  445. 'S' => '', // fractional second
  446. 'SS' => '', // fractional second
  447. 'SSS' => '', // fractional second
  448. 'SSSS' => '', // fractional second
  449. 'A' => '', // milliseconds in day
  450. 'z' => '', // Timezone abbreviation
  451. 'zz' => '', // Timezone abbreviation
  452. 'zzz' => '', // Timezone abbreviation
  453. 'zzzz' => '', // Timezone full name, not supported by php but we fallback
  454. 'Z' => '', // Difference to Greenwich time (GMT) in hours
  455. 'ZZ' => '', // Difference to Greenwich time (GMT) in hours
  456. 'ZZZ' => '', // Difference to Greenwich time (GMT) in hours
  457. 'ZZZZ' => '', // Time Zone: long localized GMT (=OOOO) e.g. GMT-08:00
  458. 'ZZZZZ' => '', // Time Zone: ISO8601 extended hms? (=XXXXX)
  459. 'O' => '', // Time Zone: short localized GMT e.g. GMT-8
  460. 'OOOO' => '', // Time Zone: long localized GMT (=ZZZZ) e.g. GMT-08:00
  461. 'v' => '', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
  462. 'vvvv' => '', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
  463. 'V' => '', // Time Zone: short time zone ID
  464. 'VV' => '', // Time Zone: long time zone ID
  465. 'VVV' => '', // Time Zone: time zone exemplar city
  466. 'VVVV' => '', // Time Zone: generic location (falls back to OOOO) using the ICU defined fallback here
  467. 'X' => '', // Time Zone: ISO8601 basic hm?, with Z for 0, e.g. -08, +0530, Z
  468. 'XX' => '', // Time Zone: ISO8601 basic hm, with Z, e.g. -0800, Z
  469. 'XXX' => '', // Time Zone: ISO8601 extended hm, with Z, e.g. -08:00, Z
  470. 'XXXX' => '', // Time Zone: ISO8601 basic hms?, with Z, e.g. -0800, -075258, Z
  471. 'XXXXX' => '', // Time Zone: ISO8601 extended hms?, with Z, e.g. -08:00, -07:52:58, Z
  472. 'x' => '', // Time Zone: ISO8601 basic hm?, without Z for 0, e.g. -08, +0530
  473. 'xx' => '', // Time Zone: ISO8601 basic hm, without Z, e.g. -0800
  474. 'xxx' => '', // Time Zone: ISO8601 extended hm, without Z, e.g. -08:00
  475. 'xxxx' => '', // Time Zone: ISO8601 basic hms?, without Z, e.g. -0800, -075258
  476. 'xxxxx' => '', // Time Zone: ISO8601 extended hms?, without Z, e.g. -08:00, -07:52:58
  477. ]));
  478. }
  479. /**
  480. * Converts a date format pattern from [php date() function format][] to [jQuery UI date format][].
  481. *
  482. * The conversion is limited to date patterns that do not use escaped characters.
  483. * Patterns like `jS \o\f F Y` which will result in a date like `1st of December 2014` may not be converted correctly
  484. * because of the use of escaped characters.
  485. *
  486. * Pattern constructs that are not supported by the jQuery UI format will be removed.
  487. *
  488. * [php date() function format]: https://secure.php.net/manual/en/function.date.php
  489. * [jQuery UI date format]: http://api.jqueryui.com/datepicker/#utility-formatDate
  490. *
  491. * @param string $pattern date format pattern in php date()-function format.
  492. * @return string The converted date format pattern.
  493. */
  494. public static function convertDatePhpToJui($pattern)
  495. {
  496. // https://secure.php.net/manual/en/function.date.php
  497. return strtr($pattern, [
  498. // Day
  499. 'd' => 'dd', // Day of the month, 2 digits with leading zeros 01 to 31
  500. 'D' => 'D', // A textual representation of a day, three letters Mon through Sun
  501. 'j' => 'd', // Day of the month without leading zeros 1 to 31
  502. 'l' => 'DD', // A full textual representation of the day of the week Sunday through Saturday
  503. 'N' => '', // ISO-8601 numeric representation of the day of the week, 1 (for Monday) through 7 (for Sunday)
  504. 'S' => '', // English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
  505. 'w' => '', // Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
  506. 'z' => 'o', // The day of the year (starting from 0) 0 through 365
  507. // Week
  508. 'W' => '', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) Example: 42 (the 42nd week in the year)
  509. // Month
  510. 'F' => 'MM', // A full textual representation of a month, January through December
  511. 'm' => 'mm', // Numeric representation of a month, with leading zeros 01 through 12
  512. 'M' => 'M', // A short textual representation of a month, three letters Jan through Dec
  513. 'n' => 'm', // Numeric representation of a month, without leading zeros 1 through 12
  514. 't' => '', // Number of days in the given month 28 through 31
  515. // Year
  516. 'L' => '', // Whether it's a leap year, 1 if it is a leap year, 0 otherwise.
  517. 'o' => '', // ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead.
  518. 'Y' => 'yy', // A full numeric representation of a year, 4 digits Examples: 1999 or 2003
  519. 'y' => 'y', // A two digit representation of a year Examples: 99 or 03
  520. // Time
  521. 'a' => '', // Lowercase Ante meridiem and Post meridiem, am or pm
  522. 'A' => '', // Uppercase Ante meridiem and Post meridiem, AM or PM, not supported by ICU but we fallback to lowercase
  523. 'B' => '', // Swatch Internet time 000 through 999
  524. 'g' => '', // 12-hour format of an hour without leading zeros 1 through 12
  525. 'G' => '', // 24-hour format of an hour without leading zeros 0 to 23h
  526. 'h' => '', // 12-hour format of an hour with leading zeros, 01 to 12 h
  527. 'H' => '', // 24-hour format of an hour with leading zeros, 00 to 23 h
  528. 'i' => '', // Minutes with leading zeros 00 to 59
  529. 's' => '', // Seconds, with leading zeros 00 through 59
  530. 'u' => '', // Microseconds. Example: 654321
  531. // Timezone
  532. 'e' => '', // Timezone identifier. Examples: UTC, GMT, Atlantic/Azores
  533. 'I' => '', // Whether or not the date is in daylight saving time, 1 if Daylight Saving Time, 0 otherwise.
  534. 'O' => '', // Difference to Greenwich time (GMT) in hours, Example: +0200
  535. 'P' => '', // Difference to Greenwich time (GMT) with colon between hours and minutes, Example: +02:00
  536. 'T' => '', // Timezone abbreviation, Examples: EST, MDT ...
  537. 'Z' => '', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
  538. // Full Date/Time
  539. 'c' => 'yyyy-MM-dd', // ISO 8601 date, e.g. 2004-02-12T15:19:21+00:00, skipping the time here because it is not supported
  540. 'r' => 'D, d M yy', // RFC 2822 formatted date, Example: Thu, 21 Dec 2000 16:01:07 +0200, skipping the time here because it is not supported
  541. 'U' => '@', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
  542. ]);
  543. }
  544. }