PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/utilities/date.php

https://github.com/joebushi/joomla
PHP | 409 lines | 196 code | 35 blank | 178 comment | 18 complexity | c155f89ea0f2a100210eca5a1c037ba9 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @package Joomla.Framework
  5. * @subpackage Utilities
  6. * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. // No direct access
  10. defined('JPATH_BASE') or die;
  11. /**
  12. * JDate is a class that stores a date and provides logic to manipulate
  13. * and render that date in a variety of formats.
  14. *
  15. * @package Joomla.Framework
  16. * @subpackage Utilities
  17. * @since 1.5
  18. */
  19. class JDate extends DateTime
  20. {
  21. const DAY_ABBR = "\x021\x03";
  22. const DAY_NAME = "\x022\x03";
  23. const MONTH_ABBR = "\x023\x03";
  24. const MONTH_NAME = "\x024\x03";
  25. /**
  26. * The format string to be applied when using the __toString() magic method.
  27. *
  28. * @var string
  29. * @since 1.6
  30. */
  31. public static $format = 'Y-m-d H:i:s';
  32. /**
  33. * Placeholder for a DateTimeZone object with GMT as the time zone.
  34. *
  35. * @var object
  36. * @since 1.6
  37. */
  38. protected static $gmt;
  39. /**
  40. * Placeholder for a DateTimeZone object with the default server
  41. * time zone as the time zone.
  42. *
  43. * @var object
  44. * @since 1.6
  45. */
  46. protected static $stz;
  47. /**
  48. * An array of offsets and time zone strings representing the available
  49. * options from Joomla! 1.5 and below.
  50. *
  51. * @deprecated Deprecated since 1.6
  52. *
  53. * @var array
  54. * @since 1.6
  55. */
  56. protected static $offsets = array(
  57. -12 => 'Etc/GMT-12',
  58. -11 => 'Pacific/Midway',
  59. -10 => 'Pacific/Honolulu',
  60. -9.5 => 'Pacific/Marquesas',
  61. -9 => 'US/Alaska',
  62. -8 => 'US/Pacific',
  63. -7 => 'US/Mountain',
  64. -6 => 'US/Central',
  65. -5 => 'US/Eastern',
  66. -4.5 => 'America/Caracas',
  67. -4 => 'America/Barbados',
  68. -3.5 => 'Canada/Newfoundland',
  69. -3 => 'America/Buenos_Aires',
  70. -2 => 'Atlantic/South_Georgia',
  71. -1 => 'Atlantic/Azores',
  72. 0 => 'Europe/London',
  73. 1 => 'Europe/Amsterdam',
  74. 2 => 'Europe/Istanbul',
  75. 3 => 'Asia/Riyadh',
  76. 3.5 => 'Asia/Tehran',
  77. 4 => 'Asia/Muscat',
  78. 4.5 => 'Asia/Kabul',
  79. 5 => 'Asia/Karachi',
  80. 5.5 => 'Asia/Calcutta',
  81. 5.75 => 'Asia/Katmandu',
  82. 6 => 'Asia/Dhaka',
  83. 6.30 => 'Indian/Cocos',
  84. 7 => 'Asia/Bangkok',
  85. 8 => 'Australia/Perth',
  86. 8.75 => 'Australia/West',
  87. 9 => 'Asia/Tokyo',
  88. 9.5 => 'Australia/Adelaide',
  89. 10 => 'Australia/Brisbane',
  90. 10.5 => 'Australia/Lord_Howe',
  91. 11 => 'Pacific/Kosrae',
  92. 11.30 => 'Pacific/Norfolk',
  93. 12 => 'Pacific/Auckland',
  94. 12.75 => 'Pacific/Chatham',
  95. 13 => 'Pacific/Tongatapu',
  96. 14 => 'Pacific/Kiritimati'
  97. );
  98. /**
  99. * The DateTimeZone object for usage in rending dates as strings.
  100. *
  101. * @var object
  102. * @since 1.6
  103. */
  104. protected $_tz;
  105. /**
  106. * Constructor.
  107. *
  108. * @param string String in a format accepted by strtotime(), defaults to "now".
  109. * @param mixed Time zone to be used for the date.
  110. * @return void
  111. * @since 1.5
  112. *
  113. * @throws JException
  114. */
  115. public function __construct($date = 'now', $tz = null)
  116. {
  117. // Create the base GMT and server time zone objects.
  118. if (empty(self::$gmt) || empty(self::$stz))
  119. {
  120. self::$gmt = new DateTimeZone('GMT');
  121. self::$stz = new DateTimeZone(@date_default_timezone_get());
  122. }
  123. // If the time zone object is not set, attempt to build it.
  124. if (!$tz instanceof DateTimeZone)
  125. {
  126. if($tz === null) {
  127. $tz = self::$gmt;
  128. }
  129. // Translate from offset.
  130. elseif (is_numeric($tz)) {
  131. $tz = new DateTimeZone(self::$offsets[$tz]);
  132. }
  133. elseif (is_string($tz)) {
  134. $tz = new DateTimeZone($tz);
  135. }
  136. }
  137. // If the date is numeric assume a unix timestamp and convert it.
  138. $date = is_numeric($date) ? date('c', $date) : $date;
  139. // Call the DateTime constructor.
  140. parent::__construct($date, $tz);
  141. // Set the timezone object for access later.
  142. $this->_tz = $tz;
  143. }
  144. /**
  145. * Magic method to render the date object in the format specified in the public
  146. * static member JDate::$format.
  147. *
  148. * @return string The date as a formatted string.
  149. * @since 1.6
  150. */
  151. public function __toString()
  152. {
  153. return (string) parent::format(self::$format);
  154. }
  155. /**
  156. * Get the time offset from GMT in hours or seconds.
  157. *
  158. * @param boolean True to return the value in hours.
  159. * @return float The time offset from GMT either in hours in seconds.
  160. * @since 1.6
  161. */
  162. public function getOffsetFromGMT($hours = false)
  163. {
  164. return (float) $hours ? ($this->_tz->getOffset($this) / 3600) : $this->_tz->getOffset($this);
  165. }
  166. /**
  167. * Gets the date as a formatted string.
  168. *
  169. * @param string The date format specification string (see {@link PHP_MANUAL#date})
  170. * @param boolean True to return the date string in the local time zone, false to return it in GMT.
  171. * @return string The date string in the specified format format.
  172. * @since 1.6
  173. */
  174. public function format($format, $local = true)
  175. {
  176. // Do string replacements for date format options that can be translated.
  177. $format = preg_replace('/[^\\\]D/', self::DAY_ABBR, $format);
  178. $format = preg_replace('/[^\\\]l/', self::DAY_NAME, $format);
  179. $format = preg_replace('/[^\\\]F/', self::MONTH_ABBR, $format);
  180. $format = preg_replace('/[^\\\]M/', self::MONTH_NAME, $format);
  181. // If the returned time should not be local use GMT.
  182. if (!$local) {
  183. parent::setTimezone(self::$gmt);
  184. }
  185. // Format the date.
  186. $return = parent::format($format);
  187. // Manually modify the month and day strings in the formated time.
  188. if (strpos($return, self::DAY_ABBR) !== false) {
  189. $return = str_replace(self::DAY_ABBR, $this->_dayToString(parent::format('w'), true), $return);
  190. }
  191. if (strpos($return, self::DAY_NAME) !== false) {
  192. $return = str_replace(self::DAY_NAME, $this->_dayToString(parent::format('w')), $return);
  193. }
  194. if (strpos($return, self::MONTH_ABBR) !== false) {
  195. $return = str_replace(self::MONTH_ABBR, $this->_monthToString(parent::format('n'), true), $return);
  196. }
  197. if (strpos($return, self::MONTH_NAME) !== false) {
  198. $return = str_replace(self::MONTH_NAME, $this->_monthToString(parent::format('n')), $return);
  199. }
  200. if (!$local) {
  201. parent::setTimezone($this->_tz);
  202. }
  203. return $return;
  204. }
  205. /**
  206. * Gets the date as an RFC 822 string. IETF RFC 2822 supercedes RFC 822 and its definition
  207. * can be found at the IETF Web site.
  208. *
  209. * @link http://www.ietf.org/rfc/rfc2822.txt
  210. *
  211. * @param boolean True to return the date string in the local time zone, false to return it in GMT.
  212. * @return string The date string in RFC 822 format.
  213. * @since 1.5
  214. */
  215. public function toRFC822($local = false)
  216. {
  217. return $this->format(DATE_RFC822, $local);
  218. }
  219. /**
  220. * Gets the date as an ISO 8601 string. IETF RFC 3339 defines the ISO 8601 format
  221. * and it can be found at the IETF Web site.
  222. *
  223. * @link http://www.ietf.org/rfc/rfc3339.txt
  224. *
  225. * @param boolean True to return the date string in the local time zone, false to return it in GMT.
  226. * @return string The date string in ISO 8601 format.
  227. * @since 1.5
  228. */
  229. public function toISO8601($local = false)
  230. {
  231. return $this->format(DATE_ISO8601, $local);
  232. }
  233. /**
  234. * Gets the date as an MySQL datetime string.
  235. *
  236. * @link http://dev.mysql.com/doc/refman/5.0/en/datetime.html
  237. *
  238. * @param boolean True to return the date string in the local time zone, false to return it in GMT.
  239. * @return string The date string in MySQL datetime format.
  240. * @since 1.5
  241. */
  242. public function toMySQL($local = false)
  243. {
  244. return $this->format('Y-m-d H:i:s', $local);
  245. }
  246. /**
  247. * Gets the date as UNIX time stamp.
  248. *
  249. * @return integer The date as a UNIX timestamp.
  250. * @since 1.5
  251. */
  252. public function toUnix()
  253. {
  254. return (int) parent::format('U');
  255. }
  256. /**
  257. * Method to wrap the setTimezone() function and set the internal
  258. * time zone object.
  259. *
  260. * @param object The new DateTimeZone object.
  261. * @return object The old DateTimeZone object.
  262. * @since 1.6
  263. */
  264. public function setTimezone(DateTimeZone $tz)
  265. {
  266. $this->_tz = $tz;
  267. return parent::setTimezone($tz);
  268. }
  269. /**
  270. * Set the date offset (in hours).
  271. *
  272. * @deprecated Deprecated since 1.6
  273. *
  274. * @param float The offset in hours.
  275. * @return boolean True on success.
  276. * @since 1.5
  277. */
  278. public function setOffset($offset)
  279. {
  280. // Only set the timezone if the offset exists.
  281. if (isset(self::$offsets[$offset]))
  282. {
  283. $this->_tz = new DateTimeZone(self::$offsets[$offset]);
  284. $this->setTimezone($this->_tz);
  285. return true;
  286. }
  287. return false;
  288. }
  289. /**
  290. * Gets the date in a specific format
  291. *
  292. * Returns a string formatted according to the given format. Month and weekday names and
  293. * other language dependent strings respect the current locale
  294. *
  295. * @deprecated Deprecated since 1.6, use JDate::format() instead.
  296. *
  297. * @param string The date format specification string (see {@link PHP_MANUAL#strftime})
  298. * @param boolean True to return the date string in the local time zone, false to return it in GMT.
  299. * @return string The date as a formatted string.
  300. * @since 1.5
  301. */
  302. public function toFormat($format = '%Y-%m-%d %H:%M:%S', $local = true)
  303. {
  304. // Generate the timestamp.
  305. $time = (int) parent::format('U');
  306. // If the returned time should be local add the GMT offset.
  307. if ($local) {
  308. $time += $this->getOffsetFromGMT();
  309. }
  310. // Manually modify the month and day strings in the format.
  311. if (strpos($format, '%a') !== false) {
  312. $format = str_replace('%a', $this->_dayToString(date('w', $time), true), $format);
  313. }
  314. if (strpos($format, '%A') !== false) {
  315. $format = str_replace('%A', $this->_dayToString(date('w', $time)), $format);
  316. }
  317. if (strpos($format, '%b') !== false) {
  318. $format = str_replace('%b', $this->_monthToString(date('n', $time), true), $format);
  319. }
  320. if (strpos($format, '%B') !== false) {
  321. $format = str_replace('%B', $this->_monthToString(date('n', $time)), $format);
  322. }
  323. // Generate the formatted string.
  324. $date = strftime($format, $time);
  325. return $date;
  326. }
  327. /**
  328. * Translates month number to a string.
  329. *
  330. * @param integer The numeric month of the year.
  331. * @param boolean Return the abreviated month string?
  332. * @return string The month of the year.
  333. * @since 1.5
  334. */
  335. protected function _monthToString($month, $abbr = false)
  336. {
  337. switch ($month)
  338. {
  339. case 1: return $abbr ? JText::_('JANUARY_SHORT') : JText::_('JANUARY');
  340. case 2: return $abbr ? JText::_('FEBRUARY_SHORT') : JText::_('FEBRUARY');
  341. case 3: return $abbr ? JText::_('MARCH_SHORT') : JText::_('MARCH');
  342. case 4: return $abbr ? JText::_('APRIL_SHORT') : JText::_('APRIL');
  343. case 5: return $abbr ? JText::_('MAY_SHORT') : JText::_('MAY');
  344. case 6: return $abbr ? JText::_('JUNE_SHORT') : JText::_('JUNE');
  345. case 7: return $abbr ? JText::_('JULY_SHORT') : JText::_('JULY');
  346. case 8: return $abbr ? JText::_('AUGUST_SHORT') : JText::_('AUGUST');
  347. case 9: return $abbr ? JText::_('SEPTEMBER_SHORT') : JText::_('SEPTEMBER');
  348. case 10: return $abbr ? JText::_('OCTOBER_SHORT') : JText::_('OCTOBER');
  349. case 11: return $abbr ? JText::_('NOVEMBER_SHORT') : JText::_('NOVEMBER');
  350. case 12: return $abbr ? JText::_('DECEMBER_SHORT') : JText::_('DECEMBER');
  351. }
  352. }
  353. /**
  354. * Translates day of week number to a string.
  355. *
  356. * @param integer The numeric day of the week.
  357. * @param boolean Return the abreviated day string?
  358. * @return string The day of the week.
  359. * @since 1.5
  360. */
  361. protected function _dayToString($day, $abbr = false)
  362. {
  363. switch ($day)
  364. {
  365. case 0: return $abbr ? JText::_('SUN') : JText::_('SUNDAY');
  366. case 1: return $abbr ? JText::_('MON') : JText::_('MONDAY');
  367. case 2: return $abbr ? JText::_('TUE') : JText::_('TUESDAY');
  368. case 3: return $abbr ? JText::_('WED') : JText::_('WEDNESDAY');
  369. case 4: return $abbr ? JText::_('THU') : JText::_('THURSDAY');
  370. case 5: return $abbr ? JText::_('FRI') : JText::_('FRIDAY');
  371. case 6: return $abbr ? JText::_('SAT') : JText::_('SATURDAY');
  372. }
  373. }
  374. }