PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/symphony/lib/core/class.datetimeobj.php

https://github.com/vlad-ghita/symphony-2
PHP | 450 lines | 176 code | 50 blank | 224 comment | 37 complexity | 6aea729efe43451a45d22ec76c451b76 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014
  1. <?php
  2. /**
  3. * @package core
  4. */
  5. /**
  6. * The DateTimeObj provides static functions regarding dates in Symphony.
  7. * Symphony will set the default timezone of the system using the value from
  8. * the Configuration values. Alternatively a new settings can be set using the
  9. * `setSettings` function. Symphony parses all input dates against the Configuration
  10. * date formats by default for better support with non English dates.
  11. */
  12. Class DateTimeObj {
  13. /**
  14. * Holds the various settings for the formats that the `DateTimeObj` should
  15. * use when parsing input dates.
  16. *
  17. * @since Symphony 2.2.4
  18. * @var array
  19. */
  20. private static $settings = array();
  21. /**
  22. * This function takes an array of settings for `DateTimeObj` to use when parsing
  23. * input dates. The following settings are supported, `time_format`, `date_format`,
  24. * `datetime_separator` and `timezone`. This equates to Symphony's default `region`
  25. * group set in the `Configuration` class. If any of these values are not provided
  26. * the class will fallback to existing `self::$settings` values
  27. *
  28. * @since Symphony 2.2.4
  29. * @param array $settings
  30. * An associative array of formats for this class to use to format
  31. * dates
  32. */
  33. public static function setSettings(array $settings = array()) {
  34. // Date format
  35. if(isset($settings['date_format'])) {
  36. self::$settings['date_format'] = $settings['date_format'];
  37. }
  38. // Time format
  39. if(isset($settings['time_format'])) {
  40. self::$settings['time_format'] = $settings['time_format'];
  41. }
  42. // Datetime separator
  43. if(isset($settings['datetime_separator'])) {
  44. self::$settings['datetime_separator'] = $settings['datetime_separator'];
  45. }
  46. else if (!isset(self::$settings['datetime_separator'])) {
  47. self::$settings['datetime_separator'] = ' ';
  48. }
  49. // Datetime format
  50. if(isset($settings['datetime_format'])) {
  51. self::$settings['datetime_format'] = $settings['datetime_format'];
  52. }
  53. else {
  54. self::$settings['datetime_format'] = self::$settings['date_format'] . self::$settings['datetime_separator'] . self::$settings['time_format'];
  55. }
  56. // Timezone
  57. if(isset($settings['timezone']) && !empty($settings['timezone'])) {
  58. self::$settings['timezone'] = $settings['timezone'];
  59. self::setDefaultTimezone($settings['timezone']);
  60. }
  61. }
  62. /**
  63. * Accessor function for the settings of the DateTimeObj. Currently
  64. * the available settings are `time_format`, `date_format`,
  65. * `datetime_format` and `datetime_separator`. If `$name` is not
  66. * provided, the entire `$settings` array is returned.
  67. *
  68. * @since Symphony 2.2.4
  69. * @param string $name
  70. * @return array|string|null
  71. * If `$name` is omitted this function returns array.
  72. * If `$name` is not set, this fucntion returns `null`
  73. * If `$name` is set, this function returns string
  74. */
  75. public static function getSetting($name = null) {
  76. if(is_null($name)) return self::$settings;
  77. if(isset(self::$settings[$name])) return self::$settings[$name];
  78. return null;
  79. }
  80. /**
  81. * Uses PHP's date_default_timezone_set function to set the system
  82. * timezone. If the timezone provided is invalid, a `E_USER_WARNING` will be
  83. * raised.
  84. *
  85. * @link http://php.net/manual/en/function.date-default-timezone-set.php
  86. * @link http://www.php.net/manual/en/timezones.php
  87. * @param string $timezone
  88. * A valid timezone identifier, such as UTC or Europe/Lisbon
  89. */
  90. public static function setDefaultTimezone($timezone){
  91. if(!@date_default_timezone_set($timezone)) trigger_error(__('Invalid timezone %s', array($timezone)), E_USER_WARNING);
  92. }
  93. /**
  94. * Validate a given date and time string
  95. *
  96. * @param string $string
  97. * A date and time string or timestamp to validate
  98. * @return boolean
  99. * Returns true for valid dates, otherwise false
  100. */
  101. public static function validate($string) {
  102. try {
  103. if(is_numeric($string) && (int)$string == $string) {
  104. $date = new DateTime('@' . $string);
  105. }
  106. else {
  107. $date = self::parse($string);
  108. }
  109. }
  110. catch(Exception $ex) {
  111. return false;
  112. }
  113. // String is empty or not a valid date
  114. if(empty($string) || $date === false) {
  115. return false;
  116. }
  117. // String is a valid date
  118. else {
  119. return true;
  120. }
  121. }
  122. /**
  123. * Given a `$format`, and a `$timestamp`,
  124. * return the date in the format provided. This function is a basic
  125. * wrapper for PHP's DateTime object. If the `$timestamp` is omitted,
  126. * the current timestamp will be used. Optionally, you pass a
  127. * timezone identifier with this function to localise the output
  128. *
  129. * If you like to display a date in the backend, please make use
  130. * of `DateTimeObj::format()` which allows date and time localization
  131. *
  132. * @see class.datetimeobj.php#format()
  133. * @link http://www.php.net/manual/en/book.datetime.php
  134. * @param string $format
  135. * A valid PHP date format
  136. * @param null|string $timestamp (optional)
  137. * A unix timestamp to format. 'now' or omitting this parameter will
  138. * result in the current time being used
  139. * @param string $timezone (optional)
  140. * The timezone associated with the timestamp
  141. * @return string|boolean
  142. * The formatted date, of if the date could not be parsed, false.
  143. */
  144. public static function get($format, $timestamp = 'now', $timezone = null) {
  145. return self::format($timestamp, $format, false, $timezone);
  146. }
  147. /**
  148. * Formats the given date and time `$string` based on the given `$format`.
  149. * Optionally the result will be localized and respect a timezone differing
  150. * from the system default. The default output is ISO 8601.
  151. *
  152. * @since Symphony 2.2.1
  153. * @param string $string (optional)
  154. * A string containing date and time, defaults to the current date and time
  155. * @param string $format (optional)
  156. * A valid PHP date format, defaults to ISO 8601
  157. * @param boolean $localize (optional)
  158. * Localizes the output, if true, defaults to true
  159. * @param string $timezone (optional)
  160. * The timezone associated with the timestamp
  161. * @return string|boolean
  162. * The formatted date, or if the date could not be parsed, false.
  163. */
  164. public static function format($string = 'now', $format = DateTime::ISO8601, $localize = true, $timezone = null) {
  165. // Parse date
  166. $date = self::parse($string);
  167. if($date === false) return false;
  168. // Timezone
  169. // If a timezone was given, apply it
  170. if(!is_null($timezone)) {
  171. $date->setTimezone(new DateTimeZone($timezone));
  172. }
  173. // No timezone given, apply the default timezone
  174. else if (isset(self::$settings['timezone'])) {
  175. $date->setTimezone(new DateTimeZone(self::$settings['timezone']));
  176. }
  177. // Format date
  178. $date = $date->format($format);
  179. // Localize date
  180. // Convert date string from English back to the activated Language
  181. if($localize === true) {
  182. $date = Lang::localizeDate($date);
  183. }
  184. // Return custom formatted date, use ISO 8601 date by default
  185. return $date;
  186. }
  187. /**
  188. * Parses the given string and returns a DateTime object.
  189. *
  190. * @since Symphony 2.3
  191. * @param string $string (optional)
  192. * A string containing date and time, defaults to the current date and time
  193. * @return DateTime|boolean
  194. * The DateTime object, or if the date could not be parsed, false.
  195. */
  196. public static function parse($string) {
  197. // Current date and time
  198. if($string == 'now' || empty($string)) {
  199. $date = new DateTime();
  200. }
  201. // Timestamp
  202. elseif(is_numeric($string)) {
  203. $date = new DateTime('@' . $string);
  204. }
  205. // Attempt to parse the date provided against the Symphony configuration setting
  206. // in an effort to better support multilingual date formats. Should this fail
  207. // this block will fallback to just passing the date to DateTime constructor,
  208. // which will parse the date assuming it's in an American format.
  209. else {
  210. // Standardize date
  211. // Convert date string to English
  212. $string = Lang::standardizeDate($string);
  213. // PHP 5.3: Apply Symphony date format using `createFromFormat`
  214. $date = DateTime::createFromFormat(self::$settings['datetime_format'], $string);
  215. if($date === false) {
  216. $date = DateTime::createFromFormat(self::$settings['date_format'], $string);
  217. }
  218. // Handle dates that are in a different format to Symphony's config
  219. // DateTime is much the same as `strtotime` and will handle relative
  220. // dates.
  221. if($date === false) {
  222. try {
  223. $date = new DateTime($string);
  224. }
  225. catch(Exception $ex) {
  226. // Invalid date, it can't be parsed
  227. return false;
  228. }
  229. }
  230. // If the date is still invalid, just return false.
  231. if($date === false) {
  232. return false;
  233. }
  234. }
  235. // Return custom formatted date, use ISO 8601 date by default
  236. return $date;
  237. }
  238. /**
  239. * A wrapper for get, this function will force the GMT timezone.
  240. *
  241. * @param string $format
  242. * A valid PHP date format
  243. * @param null|string $timestamp (optional)
  244. * A unix timestamp to format. Omitting this parameter will
  245. * result in the current time being used
  246. * @return string
  247. * The formatted date in GMT
  248. */
  249. public static function getGMT($format, $timestamp = 'now'){
  250. return self::format($timestamp, $format, false, 'GMT');
  251. }
  252. /**
  253. * This functions acts as a standard way to get the zones
  254. * available on the system.
  255. *
  256. * @since Symphony 2.3
  257. * @link http://au2.php.net/manual/en/class.datetimezone.php
  258. * @return array
  259. */
  260. public static function getZones() {
  261. $ref = new ReflectionClass('DateTimeZone');
  262. return $ref->getConstants();
  263. }
  264. /**
  265. * This functions acts as a standard way to get the timezones
  266. * regardless of PHP version. It accepts a single parameter,
  267. * zone, which returns the timezones associated with that 'zone'
  268. *
  269. * @since Symphony 2.3
  270. * @link http://au2.php.net/manual/en/class.datetimezone.php
  271. * @link http://au2.php.net/manual/en/datetimezone.listidentifiers.php
  272. * @param string $zone
  273. * The zone for the timezones the field wants. This maps to the
  274. * DateTimeZone constants
  275. * @return array
  276. */
  277. public static function getTimezones($zone = null) {
  278. return DateTimeZone::listIdentifiers(constant('DateTimeZone::' . $zone));
  279. }
  280. /**
  281. * Loads all available timezones using `getTimezones()` and builds an
  282. * array where timezones are grouped by their region (Europe/America etc.)
  283. * The options array that is returned is designed to be used with
  284. * `Widget::Select`
  285. *
  286. * @since Symphony 2.3
  287. * @see core.DateTimeObj#getTimezones()
  288. * @see core.Widget#Select()
  289. * @param string $selected
  290. * A preselected timezone, defaults to null
  291. * @return array
  292. * An associative array, for use with `Widget::Select`
  293. */
  294. public static function getTimezonesSelectOptions($selected = null){
  295. $zones = self::getZones();
  296. $groups = array();
  297. foreach($zones as $zone => $value) {
  298. if($value >= 1024) break;
  299. $timezones = self::getTimezones($zone);
  300. $options = array();
  301. foreach($timezones as $timezone) {
  302. $tz = new DateTime('now', new DateTimeZone($timezone));
  303. $options[] = array($timezone, ($timezone == $selected), sprintf("%s %s",
  304. str_replace('_', ' ', substr(strrchr($timezone, '/'),1)),
  305. $tz->format('P')
  306. ));
  307. }
  308. $groups[] = array('label' => ucwords(strtolower($zone)), 'options' => $options);
  309. }
  310. return $groups;
  311. }
  312. /**
  313. * Returns an array of the date formats Symphony supports. These
  314. * formats are a combination of valid PHP format tokens.
  315. *
  316. * @link http://au2.php.net/manual/en/function.date.php
  317. * @since Symphony 2.3
  318. * @return array
  319. */
  320. public static function getDateFormats(){
  321. return array(
  322. 'Y/m/d', // e. g. 2014/01/02
  323. 'd/m/Y', // e. g. 01/02/2014
  324. 'm/d/Y', // e. g. 01/02/2014
  325. 'm/d/y', // e. g. 01/02/14
  326. 'Y-m-d', // e. g. 2014-01-02
  327. 'm-d-Y', // e. g. 01-02-2014
  328. 'm-d-y', // e. g. 01-02-14
  329. 'd.m.Y', // e. g. 02.01.2014
  330. 'j.n.Y', // e. g. 2.1.2014 - no leading zeros
  331. 'j.n.y', // e. g. 2.1.14 - no leading zeros
  332. 'd.m.Y', // e. g. 02.01.2014
  333. 'd.m.y', // e. g. 02.01.14
  334. 'd F Y', // e. g. 02 January 2014
  335. 'd M Y', // e. g. 02 Jan 2014
  336. 'j. F Y', // e. g. 2. January 2014 - no leading zeros
  337. 'j. M. Y', // e. g. 2. Jan. 2014 - no leading zeros
  338. );
  339. }
  340. /**
  341. * Returns an array of the date formats Symphony supports by applying
  342. * the format to the current datetime. The array returned is for use with
  343. * `Widget::Select()`
  344. *
  345. * @since Symphony 2.3
  346. * @see core.Widget#Select()
  347. * @param string $selected
  348. * A preselected date format, defaults to null
  349. * @return array
  350. * An associative array, for use with `Widget::Select`
  351. */
  352. public static function getDateFormatsSelectOptions($selected = null){
  353. $formats = self::getDateFormats();
  354. $options = array();
  355. foreach($formats as $option) {
  356. $leadingZero = '';
  357. if(strpos($option, 'j') !== false || strpos($option, 'n') !== false) {
  358. $leadingZero = ' (' . __('no leading zeros') . ')';
  359. }
  360. $options[] = array($option, $option == $selected, self::format('now', $option) . $leadingZero);
  361. }
  362. return $options;
  363. }
  364. /**
  365. * Returns an array of the time formats Symphony supports. These
  366. * formats are a combination of valid PHP format tokens.
  367. *
  368. * @link http://au2.php.net/manual/en/function.date.php
  369. * @since Symphony 2.3
  370. * @return array
  371. */
  372. public static function getTimeFormats(){
  373. return array(
  374. 'H:i:s', // e. g. 20:45:32
  375. 'H:i', // e. g. 20:45
  376. 'g:i:s a', // e. g. 8:45:32 pm
  377. 'g:i a', // e. g. 8:45 pm
  378. );
  379. }
  380. /**
  381. * Returns an array of the time formats Symphony supports by applying
  382. * the format to the current datetime. The array returned is for use with
  383. * `Widget::Select()`
  384. *
  385. * @since Symphony 2.3
  386. * @see core.Widget#Select()
  387. * @param string $selected
  388. * A preselected time format, defaults to null
  389. * @return array
  390. * An associative array, for use with `Widget::Select`
  391. */
  392. public static function getTimeFormatsSelectOptions($selected = null){
  393. $formats = self::getTimeFormats();
  394. $options = array();
  395. foreach($formats as $option) {
  396. $options[] = array($option, $option == $selected, self::get($option));
  397. }
  398. return $options;
  399. }
  400. }