PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/system/helpers/date.php

https://github.com/Toushi/flow
PHP | 399 lines | 182 code | 67 blank | 150 comment | 19 complexity | 1012cfbd68aa2039b99dad961eb34772 MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Date helper class.
  4. *
  5. * $Id: date.php 2663 2008-05-07 19:58:02Z Shadowhand $
  6. *
  7. * @package Core
  8. * @author Kohana Team
  9. * @copyright (c) 2007-2008 Kohana Team
  10. * @license http://kohanaphp.com/license.html
  11. */
  12. class date_Core {
  13. /**
  14. * Converts a UNIX timestamp to DOS format.
  15. *
  16. * @param integer UNIX timestamp
  17. * @return integer
  18. */
  19. public static function unix2dos($timestamp = FALSE)
  20. {
  21. $timestamp = ($timestamp === FALSE) ? getdate() : getdate($timestamp);
  22. if ($timestamp['year'] < 1980)
  23. {
  24. return (1 << 21 | 1 << 16);
  25. }
  26. $timestamp['year'] -= 1980;
  27. // What voodoo is this? I have no idea... Geert can explain it though,
  28. // and that's good enough for me.
  29. return ($timestamp['year'] << 25 | $timestamp['mon'] << 21 |
  30. $timestamp['mday'] << 16 | $timestamp['hours'] << 11 |
  31. $timestamp['minutes'] << 5 | $timestamp['seconds'] >> 1);
  32. }
  33. /**
  34. * Converts a DOS timestamp to UNIX format.
  35. *
  36. * @param integer DOS timestamp
  37. * @return integer
  38. */
  39. public static function dos2unix($timestamp = FALSE)
  40. {
  41. $sec = 2 * ($timestamp & 0x1f);
  42. $min = ($timestamp >> 5) & 0x3f;
  43. $hrs = ($timestamp >> 11) & 0x1f;
  44. $day = ($timestamp >> 16) & 0x1f;
  45. $mon = ($timestamp >> 21) & 0x0f;
  46. $year = ($timestamp >> 25) & 0x7f;
  47. return mktime($hrs, $min, $sec, $mon, $day, $year + 1980);
  48. }
  49. /**
  50. * Returns the offset (in seconds) between two time zones.
  51. * @see http://php.net/timezones
  52. *
  53. * @param string timezone that to find the offset of
  54. * @param string|boolean timezone used as the baseline
  55. * @return integer
  56. */
  57. public static function offset($remote, $local = TRUE)
  58. {
  59. static $offsets;
  60. // Default values
  61. $remote = (string) $remote;
  62. $local = ($local === TRUE) ? date_default_timezone_get() : (string) $local;
  63. // Cache key name
  64. $cache = $remote.$local;
  65. if (empty($offsets[$cache]))
  66. {
  67. // Create timezone objects
  68. $remote = new DateTimeZone($remote);
  69. $local = new DateTimeZone($local);
  70. // Create date objects from timezones
  71. $time_there = new DateTime('now', $remote);
  72. $time_here = new DateTime('now', $local);
  73. // Find the offset
  74. $offsets[$cache] = $remote->getOffset($time_there) - $local->getOffset($time_here);
  75. }
  76. return $offsets[$cache];
  77. }
  78. /**
  79. * Number of seconds in a minute, incrementing by a step.
  80. *
  81. * @param integer amount to increment each step by, 1 to 30
  82. * @param integer start value
  83. * @param integer end value
  84. * @return array A mirrored (foo => foo) array from 1-60.
  85. */
  86. public static function seconds($step = 1, $start = 0, $end = 60)
  87. {
  88. // Always integer
  89. $step = (int) $step;
  90. $seconds = array();
  91. for ($i = $start; $i < $end; $i += $step)
  92. {
  93. $seconds[$i] = ($i < 10) ? '0'.$i : $i;
  94. }
  95. return $seconds;
  96. }
  97. /**
  98. * Number of minutes in an hour, incrementing by a step.
  99. *
  100. * @param integer amount to increment each step by, 1 to 30
  101. * @return array A mirrored (foo => foo) array from 1-60.
  102. */
  103. public static function minutes($step = 5)
  104. {
  105. // Because there are the same number of minutes as seconds in this set,
  106. // we choose to re-use seconds(), rather than creating an entirely new
  107. // function. Shhhh, it's cheating! ;) There are several more of these
  108. // in the following methods.
  109. return date::seconds($step);
  110. }
  111. /**
  112. * Number of hours in a day.
  113. *
  114. * @param integer amount to increment each step by
  115. * @param boolean use 24-hour time
  116. * @param integer the hour to start at
  117. * @return array A mirrored (foo => foo) array from start-12 or start-23.
  118. */
  119. public static function hours($step = 1, $long = FALSE, $start = NULL)
  120. {
  121. // Default values
  122. $step = (int) $step;
  123. $long = (bool) $long;
  124. $hours = array();
  125. // Set the default start if none was specified.
  126. if ($start === NULL)
  127. {
  128. $start = ($long === FALSE) ? 1 : 0;
  129. }
  130. $hours = array();
  131. // 24-hour time has 24 hours, instead of 12
  132. $size = ($long === TRUE) ? 23 : 12;
  133. for ($i = $start; $i <= $size; $i += $step)
  134. {
  135. $hours[$i] = $i;
  136. }
  137. return $hours;
  138. }
  139. /**
  140. * Returns AM or PM, based on a given hour.
  141. *
  142. * @param integer number of the hour
  143. * @return string
  144. */
  145. public static function ampm($hour)
  146. {
  147. // Always integer
  148. $hour = (int) $hour;
  149. return ($hour > 11) ? 'PM' : 'AM';
  150. }
  151. /**
  152. * Adjusts a non-24-hour number into a 24-hour number.
  153. *
  154. * @param integer hour to adjust
  155. * @param string AM or PM
  156. * @return string
  157. */
  158. public static function adjust($hour, $ampm)
  159. {
  160. $hour = (int) $hour;
  161. $ampm = strtolower($ampm);
  162. switch ($ampm)
  163. {
  164. case 'am':
  165. if ($hour == 12)
  166. $hour = 0;
  167. break;
  168. case 'pm':
  169. if ($hour < 12)
  170. $hour += 12;
  171. break;
  172. }
  173. return sprintf('%02s', $hour);
  174. }
  175. /**
  176. * Number of days in month.
  177. *
  178. * @param integer number of month
  179. * @param integer number of year to check month, defaults to the current year
  180. * @return array A mirrored (foo => foo) array of the days.
  181. */
  182. public static function days($month, $year = FALSE)
  183. {
  184. static $months;
  185. // Always integers
  186. $month = (int) $month;
  187. $year = (int) $year;
  188. // Use the current year by default
  189. $year = ($year == FALSE) ? date('Y') : $year;
  190. // We use caching for months, because time functions are used
  191. if (empty($months[$year][$month]))
  192. {
  193. $months[$year][$month] = array();
  194. // Use date to find the number of days in the given month
  195. $total = date('t', mktime(1, 0, 0, $month, 1, $year)) + 1;
  196. for ($i = 1; $i < $total; $i++)
  197. {
  198. $months[$year][$month][$i] = $i;
  199. }
  200. }
  201. return $months[$year][$month];
  202. }
  203. /**
  204. * Number of months in a year
  205. *
  206. * @return array A mirrored (foo => foo) array from 1-12.
  207. */
  208. public static function months()
  209. {
  210. return date::hours();
  211. }
  212. /**
  213. * Returns an array of years between a starting and ending year.
  214. * Uses the current year +/- 5 as the max/min.
  215. *
  216. * @param integer starting year
  217. * @param integer ending year
  218. * @return array
  219. */
  220. public static function years($start = FALSE, $end = FALSE)
  221. {
  222. // Default values
  223. $start = ($start === FALSE) ? date('Y') - 5 : (int) $start;
  224. $end = ($end === FALSE) ? date('Y') + 5 : (int) $end;
  225. $years = array();
  226. // Add one, so that "less than" works
  227. $end += 1;
  228. for ($i = $start; $i < $end; $i++)
  229. {
  230. $years[$i] = $i;
  231. }
  232. return $years;
  233. }
  234. /**
  235. * Returns time difference between two timestamps, in human readable format.
  236. *
  237. * @param integer timestamp
  238. * @param integer timestamp, defaults to the current time
  239. * @param string formatting string
  240. * @return string|array
  241. */
  242. public static function timespan($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
  243. {
  244. // Array with the output formats
  245. $output = preg_split('/[^a-z]+/', strtolower((string) $output));
  246. // Invalid output
  247. if (empty($output))
  248. return FALSE;
  249. // Make the output values into keys
  250. extract(array_flip($output), EXTR_SKIP);
  251. // Default values
  252. $time1 = max(0, (int) $time1);
  253. $time2 = empty($time2) ? time() : max(0, (int) $time2);
  254. // Calculate timespan (seconds)
  255. $timespan = abs($time1 - $time2);
  256. // All values found using Google Calculator.
  257. // Years and months do not match the formula exactly, due to leap years.
  258. // Years ago, 60 * 60 * 24 * 365
  259. isset($years) and $timespan -= 31556926 * ($years = (int) floor($timespan / 31556926));
  260. // Months ago, 60 * 60 * 24 * 30
  261. isset($months) and $timespan -= 2629744 * ($months = (int) floor($timespan / 2629743.83));
  262. // Weeks ago, 60 * 60 * 24 * 7
  263. isset($weeks) and $timespan -= 604800 * ($weeks = (int) floor($timespan / 604800));
  264. // Days ago, 60 * 60 * 24
  265. isset($days) and $timespan -= 86400 * ($days = (int) floor($timespan / 86400));
  266. // Hours ago, 60 * 60
  267. isset($hours) and $timespan -= 3600 * ($hours = (int) floor($timespan / 3600));
  268. // Minutes ago, 60
  269. isset($minutes) and $timespan -= 60 * ($minutes = (int) floor($timespan / 60));
  270. // Seconds ago, 1
  271. isset($seconds) and $seconds = $timespan;
  272. // Remove the variables that cannot be accessed
  273. unset($timespan, $time1, $time2);
  274. // Deny access to these variables
  275. $deny = array_flip(array('deny', 'key', 'difference', 'output'));
  276. // Return the difference
  277. $difference = array();
  278. foreach ($output as $key)
  279. {
  280. if (isset($$key) AND ! isset($deny[$key]))
  281. {
  282. // Add requested key to the output
  283. $difference[$key] = $$key;
  284. }
  285. }
  286. // Invalid output formats string
  287. if (empty($difference))
  288. return FALSE;
  289. // If only one output format was asked, don't put it in an array
  290. if (count($difference) === 1)
  291. return current($difference);
  292. // Return array
  293. return $difference;
  294. }
  295. /**
  296. * Returns time difference between two timestamps, in the format:
  297. * N year, N months, N weeks, N days, N hours, N minutes, and N seconds ago
  298. *
  299. * @param integer timestamp
  300. * @param integer timestamp, defaults to the current time
  301. * @param string formatting string
  302. * @return string
  303. */
  304. public static function timespan_string($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
  305. {
  306. if ($difference = date::timespan($time1, $time2, $output) AND is_array($difference))
  307. {
  308. // Determine the key of the last item in the array
  309. $last = end($difference);
  310. $last = key($difference);
  311. $span = array();
  312. foreach ($difference as $name => $amount)
  313. {
  314. if ($name !== $last AND $amount === 0)
  315. {
  316. // Skip empty amounts
  317. continue;
  318. }
  319. // Add the amount to the span
  320. $span[] = ($name === $last ? ' and ' : ', ').$amount.' '.($amount === 1 ? inflector::singular($name) : $name);
  321. }
  322. // Replace difference by making the span into a string
  323. $difference = trim(implode('', $span), ',');
  324. }
  325. elseif (is_int($difference))
  326. {
  327. // Single-value return
  328. $difference = $difference.' '.($difference === 1 ? inflector::singular($output) : $output);
  329. }
  330. return $difference;
  331. }
  332. } // End date