sfDateFormat.class.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. <?php
  2. /**
  3. * sfDateFormat class file.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the BSD License.
  7. *
  8. * Copyright(c) 2004 by Qiang Xue. All rights reserved.
  9. *
  10. * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
  11. * The latest version of PRADO can be obtained from:
  12. * {@link http://prado.sourceforge.net/}
  13. *
  14. * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
  15. * @version $Id: sfDateFormat.class.php 9128 2008-05-21 00:58:19Z Carl.Vondrick $
  16. * @package symfony
  17. * @subpackage i18n
  18. */
  19. /**
  20. * sfDateFormat class.
  21. *
  22. * The sfDateFormat class allows you to format dates and times with
  23. * predefined styles in a locale-sensitive manner. Formatting times
  24. * with the sfDateFormat class is similar to formatting dates.
  25. *
  26. * Formatting dates with the sfDateFormat class is a two-step process.
  27. * First, you create a formatter with the getDateInstance method.
  28. * Second, you invoke the format method, which returns a string containing
  29. * the formatted date.
  30. *
  31. * DateTime values are formatted using standard or custom patterns stored
  32. * in the properties of a DateTimeFormatInfo.
  33. *
  34. * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
  35. * @version v1.0, last update on Sat Dec 04 14:10:49 EST 2004
  36. * @package symfony
  37. * @subpackage i18n
  38. */
  39. class sfDateFormat
  40. {
  41. /**
  42. * A list of tokens and their function call.
  43. * @var array
  44. */
  45. protected $tokens = array(
  46. 'G' => 'Era',
  47. 'y' => 'year',
  48. 'M' => 'mon',
  49. 'd' => 'mday',
  50. 'h' => 'Hour12',
  51. 'H' => 'hours',
  52. 'm' => 'minutes',
  53. 's' => 'seconds',
  54. 'E' => 'wday',
  55. 'D' => 'yday',
  56. 'F' => 'DayInMonth',
  57. 'w' => 'WeekInYear',
  58. 'W' => 'WeekInMonth',
  59. 'a' => 'AMPM',
  60. 'k' => 'HourInDay',
  61. 'K' => 'HourInAMPM',
  62. 'z' => 'TimeZone'
  63. );
  64. /**
  65. * A list of methods, to be used by the token function calls.
  66. * @var array
  67. */
  68. protected $methods = array();
  69. /**
  70. * The sfDateTimeFormatInfo, containing culture specific patterns and names.
  71. * @var sfDateTimeFormatInfo
  72. */
  73. protected $formatInfo;
  74. /**
  75. * Initializes a new sfDateFormat.
  76. *
  77. * @param mixed $forrmatInfo either, null, a sfCultureInfo instance, a DateTimeFormatInfo instance, or a locale.
  78. * @return sfDateFormat instance
  79. */
  80. function __construct($formatInfo = null)
  81. {
  82. if (is_null($formatInfo))
  83. {
  84. $this->formatInfo = sfDateTimeFormatInfo::getInvariantInfo();
  85. }
  86. else if ($formatInfo instanceof sfCultureInfo)
  87. {
  88. $this->formatInfo = $formatInfo->DateTimeFormat;
  89. }
  90. else if ($formatInfo instanceof sfDateTimeFormatInfo)
  91. {
  92. $this->formatInfo = $formatInfo;
  93. }
  94. else
  95. {
  96. $this->formatInfo = sfDateTimeFormatInfo::getInstance($formatInfo);
  97. }
  98. $this->methods = get_class_methods($this);
  99. }
  100. /**
  101. * Guesses a date without calling strtotime.
  102. *
  103. * @author Olivier Verdier <Olivier.Verdier@gmail.com>
  104. * @param mixed $time the time as integer or string in strtotime format.
  105. * @param string $pattern the input pattern; default is sql date or timestamp
  106. * @return array same array as the getdate function
  107. */
  108. public function getDate($time, $pattern = null)
  109. {
  110. if (is_null($time))
  111. {
  112. return null;
  113. }
  114. // if the type is not a php timestamp
  115. $isString = (string) $time !== (string) (int) $time;
  116. if ($isString)
  117. {
  118. if (!$pattern)
  119. {
  120. if (strlen($time) == 10)
  121. {
  122. $pattern = 'i';
  123. }
  124. else // otherwise, default:
  125. {
  126. $pattern = 'I';
  127. }
  128. }
  129. $pattern = $this->getPattern($pattern);
  130. $tokens = $this->getTokens($pattern);
  131. $pregPattern = '';
  132. $matchNames = array();
  133. foreach ($tokens as $token)
  134. {
  135. if ($matchName = $this->getFunctionName($token))
  136. {
  137. $pregPattern .= '(\d+)';
  138. $matchNames[] = $matchName;
  139. }
  140. else
  141. {
  142. $pregPattern .= '[^\d]+';
  143. }
  144. }
  145. preg_match('@'.$pregPattern.'@', $time, $matches);
  146. array_shift($matches);
  147. if (count($matchNames) == count($matches))
  148. {
  149. $date = array_combine($matchNames, $matches);
  150. // guess the date if input with two digits
  151. if (strlen($date['year']) == 2)
  152. {
  153. $date['year'] = date('Y', mktime(0, 0, 0, 1, 1, $date['year']));
  154. }
  155. $date = array_map('intval', $date);
  156. }
  157. }
  158. // the last attempt has failed we fall back on the default method
  159. if (!isset($date))
  160. {
  161. if ($isString)
  162. {
  163. $numericalTime = @strtotime($time);
  164. if ($numericalTime === false)
  165. {
  166. throw new sfException(sprintf('Impossible to parse date "%s" with format "%s".', $time, $pattern));
  167. }
  168. }
  169. else
  170. {
  171. $numericalTime = $time;
  172. }
  173. $date = @getdate($numericalTime);
  174. }
  175. // we set default values for the time
  176. foreach (array('hours', 'minutes', 'seconds') as $timeDiv)
  177. {
  178. if (!isset($date[$timeDiv]))
  179. {
  180. $date[$timeDiv] = 0;
  181. }
  182. }
  183. return $date;
  184. }
  185. /**
  186. * Formats a date according to the pattern.
  187. *
  188. * @param mixed $time the time as integer or string in strtotime format.
  189. * @param string $pattern the pattern
  190. * @param string $inputPattern the input pattern
  191. * @param string $charset the charset
  192. * @return string formatted date time.
  193. */
  194. public function format($time, $pattern = 'F', $inputPattern = null, $charset = 'UTF-8')
  195. {
  196. $date = $this->getDate($time, $inputPattern);
  197. if (is_null($pattern))
  198. {
  199. $pattern = 'F';
  200. }
  201. $pattern = $this->getPattern($pattern);
  202. $tokens = $this->getTokens($pattern);
  203. for ($i = 0, $max = count($tokens); $i < $max; $i++)
  204. {
  205. $pattern = $tokens[$i];
  206. if ($pattern{0} == "'" && $pattern{strlen($pattern) - 1} == "'")
  207. {
  208. $tokens[$i] = str_replace('``````', '\'', preg_replace('/(^\')|(\'$)/', '', $pattern));
  209. }
  210. else if ($pattern == '``````')
  211. {
  212. $tokens[$i] = '\'';
  213. }
  214. else
  215. {
  216. $function = ucfirst($this->getFunctionName($pattern));
  217. if ($function != null)
  218. {
  219. $fName = 'get'.$function;
  220. if (in_array($fName, $this->methods))
  221. {
  222. $tokens[$i] = $this->$fName($date, $pattern);
  223. }
  224. else
  225. {
  226. throw new sfException(sprintf('Function %s not found.', $function));
  227. }
  228. }
  229. }
  230. }
  231. return sfToolkit::I18N_toEncoding(implode('', $tokens), $charset);
  232. }
  233. /**
  234. * For a particular token, get the corresponding function to call.
  235. *
  236. * @param string $token token
  237. * @return mixed the function if good token, null otherwise.
  238. */
  239. protected function getFunctionName($token)
  240. {
  241. if (isset($this->tokens[$token{0}]))
  242. {
  243. return $this->tokens[$token{0}];
  244. }
  245. }
  246. /**
  247. * Gets the pattern from DateTimeFormatInfo or some predefined patterns.
  248. * If the $pattern parameter is an array of 2 element, it will assume
  249. * that the first element is the date, and second the time
  250. * and try to find an appropriate pattern and apply
  251. * DateTimeFormatInfo::formatDateTime
  252. * See the tutorial documentation for futher details on the patterns.
  253. *
  254. * @param mixed $pattern a pattern.
  255. * @return string a pattern.
  256. * @see DateTimeFormatInfo::formatDateTime()
  257. */
  258. public function getPattern($pattern)
  259. {
  260. if (is_array($pattern) && count($pattern) == 2)
  261. {
  262. return $this->formatInfo->formatDateTime($this->getPattern($pattern[0]), $this->getPattern($pattern[1]));
  263. }
  264. switch ($pattern)
  265. {
  266. case 'd':
  267. return $this->formatInfo->ShortDatePattern;
  268. break;
  269. case 'D':
  270. return $this->formatInfo->LongDatePattern;
  271. break;
  272. case 'p':
  273. return $this->formatInfo->MediumDatePattern;
  274. break;
  275. case 'P':
  276. return $this->formatInfo->FullDatePattern;
  277. break;
  278. case 't':
  279. return $this->formatInfo->ShortTimePattern;
  280. break;
  281. case 'T':
  282. return $this->formatInfo->LongTimePattern;
  283. break;
  284. case 'q':
  285. return $this->formatInfo->MediumTimePattern;
  286. break;
  287. case 'Q':
  288. return $this->formatInfo->FullTimePattern;
  289. break;
  290. case 'f':
  291. return $this->formatInfo->formatDateTime($this->formatInfo->LongDatePattern, $this->formatInfo->ShortTimePattern);
  292. break;
  293. case 'F':
  294. return $this->formatInfo->formatDateTime($this->formatInfo->LongDatePattern, $this->formatInfo->LongTimePattern);
  295. break;
  296. case 'g':
  297. return $this->formatInfo->formatDateTime($this->formatInfo->ShortDatePattern, $this->formatInfo->ShortTimePattern);
  298. break;
  299. case 'G':
  300. return $this->formatInfo->formatDateTime($this->formatInfo->ShortDatePattern, $this->formatInfo->LongTimePattern);
  301. break;
  302. case 'i':
  303. return 'yyyy-MM-dd';
  304. break;
  305. case 'I':
  306. return 'yyyy-MM-dd HH:mm:ss';
  307. break;
  308. case 'M':
  309. case 'm':
  310. return 'MMMM dd';
  311. break;
  312. case 'R':
  313. case 'r':
  314. return 'EEE, dd MMM yyyy HH:mm:ss';
  315. break;
  316. case 's':
  317. return 'yyyy-MM-ddTHH:mm:ss';
  318. break;
  319. case 'u':
  320. return 'yyyy-MM-dd HH:mm:ss z';
  321. break;
  322. case 'U':
  323. return 'EEEE dd MMMM yyyy HH:mm:ss';
  324. break;
  325. case 'Y':
  326. case 'y':
  327. return 'yyyy MMMM';
  328. break;
  329. default :
  330. return $pattern;
  331. }
  332. }
  333. /**
  334. * Returns an easy to parse input pattern
  335. * yy is replaced by yyyy and h by H
  336. *
  337. * @param string $pattern pattern.
  338. * @return string input pattern
  339. */
  340. public function getInputPattern($pattern)
  341. {
  342. $pattern = $this->getPattern($pattern);
  343. $pattern = strtr($pattern, array('yyyy' => 'Y', 'h'=>'H', 'z'=>'', 'a'=>''));
  344. $pattern = strtr($pattern, array('yy'=>'yyyy', 'Y'=>'yyyy'));
  345. return trim($pattern);
  346. }
  347. /**
  348. * Tokenizes the pattern. The tokens are delimited by group of
  349. * similar characters, e.g. 'aabb' will form 2 tokens of 'aa' and 'bb'.
  350. * Any substrings, starting and ending with a single quote (')
  351. * will be treated as a single token.
  352. *
  353. * @param string $pattern pattern.
  354. * @return array string tokens in an array.
  355. */
  356. protected function getTokens($pattern)
  357. {
  358. $char = null;
  359. $tokens = array();
  360. $token = null;
  361. $text = false;
  362. for ($i = 0, $max = strlen($pattern); $i < $max; $i++)
  363. {
  364. if ($char == null || $pattern{$i} == $char || $text)
  365. {
  366. $token .= $pattern{$i};
  367. }
  368. else
  369. {
  370. $tokens[] = str_replace("''", "'", $token);
  371. $token = $pattern{$i};
  372. }
  373. if ($pattern{$i} == "'" && $text == false)
  374. {
  375. $text = true;
  376. }
  377. else if ($text && $pattern{$i} == "'" && $char == "'")
  378. {
  379. $text = true;
  380. }
  381. else if ($text && $char != "'" && $pattern{$i} == "'")
  382. {
  383. $text = false;
  384. }
  385. $char = $pattern{$i};
  386. }
  387. $tokens[] = $token;
  388. return $tokens;
  389. }
  390. // makes a unix date from our incomplete $date array
  391. protected function getUnixDate($date)
  392. {
  393. return getdate(mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
  394. }
  395. /**
  396. * Gets the year.
  397. * "yy" will return the last two digits of year.
  398. * "yyyy" will return the full integer year.
  399. *
  400. * @param array $dat getdate format.
  401. * @param string $pattern a pattern.
  402. * @return string year
  403. */
  404. protected function getYear($date, $pattern = 'yyyy')
  405. {
  406. $year = $date['year'];
  407. switch ($pattern)
  408. {
  409. case 'yy':
  410. return substr($year, 2);
  411. case 'yyyy':
  412. return $year;
  413. default:
  414. throw new sfException('The pattern for year is either "yy" or "yyyy".');
  415. }
  416. }
  417. /**
  418. * Gets the month.
  419. * "M" will return integer 1 through 12
  420. * "MM" will return the narrow month name, e.g. "J"
  421. * "MMM" will return the abrreviated month name, e.g. "Jan"
  422. * "MMMM" will return the month name, e.g. "January"
  423. *
  424. * @param array $date getdate format.
  425. * @param string $pattern a pattern.
  426. * @return string month name
  427. */
  428. protected function getMon($date, $pattern = 'M')
  429. {
  430. $month = $date['mon'];
  431. switch ($pattern)
  432. {
  433. case 'M':
  434. return $month;
  435. case 'MM':
  436. return str_pad($month, 2, '0', STR_PAD_LEFT);
  437. case 'MMM':
  438. return $this->formatInfo->AbbreviatedMonthNames[$month - 1];
  439. break;
  440. case 'MMMM':
  441. return $this->formatInfo->MonthNames[$month - 1];
  442. default:
  443. throw new sfException('The pattern for month is "M", "MM", "MMM", or "MMMM".');
  444. }
  445. }
  446. /**
  447. * Gets the day of the week.
  448. * "E" will return integer 0 (for Sunday) through 6 (for Saturday).
  449. * "EE" will return the narrow day of the week, e.g. "M"
  450. * "EEE" will return the abrreviated day of the week, e.g. "Mon"
  451. * "EEEE" will return the day of the week, e.g. "Monday"
  452. *
  453. * @param array $date getdate format.
  454. * @param string $pattern a pattern.
  455. * @return string day of the week.
  456. */
  457. protected function getWday($date, $pattern = 'EEEE')
  458. {
  459. // if the $date comes from our home-made get date
  460. if (!isset($date['wday']))
  461. {
  462. $date = $this->getUnixDate($date);
  463. }
  464. $day = $date['wday'];
  465. switch ($pattern)
  466. {
  467. case 'E':
  468. return $day;
  469. break;
  470. case 'EE':
  471. return $this->formatInfo->NarrowDayNames[$day];
  472. case 'EEE':
  473. return $this->formatInfo->AbbreviatedDayNames[$day];
  474. break;
  475. case 'EEEE':
  476. return $this->formatInfo->DayNames[$day];
  477. break;
  478. default:
  479. throw new sfException('The pattern for day of the week is "E", "EE", "EEE", or "EEEE".');
  480. }
  481. }
  482. /**
  483. * Gets the day of the month.
  484. * "d" for non-padding, "dd" will always return 2 characters.
  485. *
  486. * @param array $date getdate format.
  487. * @param string $pattern a pattern.
  488. * @return string day of the month
  489. */
  490. protected function getMday($date, $pattern = 'd')
  491. {
  492. $day = $date['mday'];
  493. switch ($pattern)
  494. {
  495. case 'd':
  496. return $day;
  497. case 'dd':
  498. return str_pad($day, 2, '0', STR_PAD_LEFT);
  499. case 'dddd':
  500. return $this->getWday($date);
  501. default:
  502. throw new sfException('The pattern for day of the month is "d", "dd" or "dddd".');
  503. }
  504. }
  505. /**
  506. * Gets the era. i.e. in gregorian, year > 0 is AD, else BC.
  507. *
  508. * @todo How to support multiple Eras?, e.g. Japanese.
  509. * @param array $date getdate format.
  510. * @param string $pattern a pattern.
  511. * @return string era
  512. */
  513. protected function getEra($date, $pattern = 'G')
  514. {
  515. if ($pattern != 'G')
  516. {
  517. throw new sfException('The pattern for era is "G".');
  518. }
  519. return $this->formatInfo->getEra($date['year'] > 0 ? 1 : 0);
  520. }
  521. /**
  522. * Gets the hours in 24 hour format, i.e. [0-23].
  523. * "H" for non-padding, "HH" will always return 2 characters.
  524. *
  525. * @param array $date getdate format.
  526. * @param string $pattern a pattern.
  527. * @return string hours in 24 hour format.
  528. */
  529. protected function getHours($date, $pattern = 'H')
  530. {
  531. $hour = $date['hours'];
  532. switch ($pattern)
  533. {
  534. case 'H':
  535. return $hour;
  536. case 'HH':
  537. return str_pad($hour, 2, '0', STR_PAD_LEFT);
  538. default:
  539. throw new sfException('The pattern for 24 hour format is "H" or "HH".');
  540. }
  541. }
  542. /**
  543. * Get the AM/PM designator, 12 noon is PM, 12 midnight is AM.
  544. *
  545. * @param array $date getdate format.
  546. * @param string $pattern a pattern.
  547. * @return string AM or PM designator
  548. */
  549. protected function getAMPM($date, $pattern = 'a')
  550. {
  551. if ($pattern != 'a')
  552. {
  553. throw new sfException('The pattern for AM/PM marker is "a".');
  554. }
  555. return $this->formatInfo->AMPMMarkers[intval($date['hours'] / 12)];
  556. }
  557. /**
  558. * Gets the hours in 12 hour format.
  559. * "h" for non-padding, "hh" will always return 2 characters.
  560. *
  561. * @param array $date getdate format.
  562. * @param string $pattern a pattern.
  563. * @return string hours in 12 hour format.
  564. */
  565. protected function getHour12($date, $pattern = 'h')
  566. {
  567. $hour = $date['hours'];
  568. $hour = ($hour == 12 | $hour == 0) ? 12 : $hour % 12;
  569. switch ($pattern)
  570. {
  571. case 'h':
  572. return $hour;
  573. case 'hh':
  574. return str_pad($hour, 2, '0', STR_PAD_LEFT);
  575. default:
  576. throw new sfException('The pattern for 24 hour format is "H" or "HH".');
  577. }
  578. }
  579. /**
  580. * Gets the minutes.
  581. * "m" for non-padding, "mm" will always return 2 characters.
  582. *
  583. * @param array $date getdate format.
  584. * @param string $pattern a pattern.
  585. * @return string minutes.
  586. */
  587. protected function getMinutes($date, $pattern = 'm')
  588. {
  589. $minutes = $date['minutes'];
  590. switch ($pattern)
  591. {
  592. case 'm':
  593. return $minutes;
  594. case 'mm':
  595. return str_pad($minutes, 2, '0', STR_PAD_LEFT);
  596. default:
  597. throw new sfException('The pattern for minutes is "m" or "mm".');
  598. }
  599. }
  600. /**
  601. * Gets the seconds.
  602. * "s" for non-padding, "ss" will always return 2 characters.
  603. *
  604. * @param array $date getdate format.
  605. * @param string $pattern a pattern.
  606. * @return string seconds
  607. */
  608. protected function getSeconds($date, $pattern = 's')
  609. {
  610. $seconds = $date['seconds'];
  611. switch ($pattern)
  612. {
  613. case 's':
  614. return $seconds;
  615. case 'ss':
  616. return str_pad($seconds, 2, '0', STR_PAD_LEFT);
  617. default:
  618. throw new sfException('The pattern for seconds is "s" or "ss".');
  619. }
  620. }
  621. /**
  622. * Gets the timezone from the server machine.
  623. *
  624. * @todo How to get the timezone for a different region?
  625. * @param array $date getdate format.
  626. * @param string $pattern a pattern.
  627. * @return string time zone
  628. */
  629. protected function getTimeZone($date, $pattern = 'z')
  630. {
  631. if ($pattern != 'z')
  632. {
  633. throw new sfException('The pattern for time zone is "z".');
  634. }
  635. return @date('T', @mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
  636. }
  637. /**
  638. * Gets the day in the year, e.g. [1-366]
  639. *
  640. * @param array $date getdate format.
  641. * @param string $pattern a pattern.
  642. * @return int hours in AM/PM format.
  643. */
  644. protected function getYday($date, $pattern = 'D')
  645. {
  646. if ($pattern != 'D')
  647. {
  648. throw new sfException('The pattern for day in year is "D".');
  649. }
  650. return $date['yday'];
  651. }
  652. /**
  653. * Gets day in the month.
  654. *
  655. * @param array $date getdate format.
  656. * @param string $pattern a pattern.
  657. * @return int day in month
  658. */
  659. protected function getDayInMonth($date, $pattern = 'FF')
  660. {
  661. switch ($pattern)
  662. {
  663. case 'F':
  664. return @date('j', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']));
  665. break;
  666. case 'FF':
  667. return @date('d', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']));
  668. break;
  669. default:
  670. throw new sfException('The pattern for day in month is "F" or "FF".');
  671. }
  672. }
  673. /**
  674. * Gets the week in the year.
  675. *
  676. * @param array $date getdate format.
  677. * @param string $pattern a pattern.
  678. * @return int week in year
  679. */
  680. protected function getWeekInYear($date, $pattern = 'w')
  681. {
  682. if ($pattern != 'w')
  683. {
  684. throw new sfException('The pattern for week in year is "w".');
  685. }
  686. return @date('W', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']));
  687. }
  688. /**
  689. * Gets week in the month.
  690. *
  691. * @param array $date getdate format.
  692. * @param string $pattern a pattern
  693. * @return int week in month
  694. */
  695. protected function getWeekInMonth($date, $pattern = 'W')
  696. {
  697. if ($pattern != 'W')
  698. {
  699. throw new sfException('The pattern for week in month is "W".');
  700. }
  701. return @date('W', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year'])) - date('W', mktime(0, 0, 0, $date['mon'], 1, $date['year']));
  702. }
  703. /**
  704. * Gets the hours [1-24].
  705. *
  706. * @param array $date getdate format.
  707. * @param string $pattern a pattern.
  708. * @return int hours [1-24]
  709. */
  710. protected function getHourInDay($date, $pattern = 'k')
  711. {
  712. if ($pattern != 'k')
  713. {
  714. throw new sfException('The pattern for hour in day is "k".');
  715. }
  716. return $date['hours'] + 1;
  717. }
  718. /**
  719. * Gets the hours in AM/PM format, e.g [1-12]
  720. *
  721. * @param array $date getdate format.
  722. * @param string $pattern a pattern.
  723. * @return int hours in AM/PM format.
  724. */
  725. protected function getHourInAMPM($date, $pattern = 'K')
  726. {
  727. if ($pattern != 'K')
  728. {
  729. throw new sfException('The pattern for hour in AM/PM is "K".');
  730. }
  731. return ($date['hours'] + 1) % 12;
  732. }
  733. }