PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/a10/lib/yii-1.1.10/utils/CTimestamp.php

http://chenjin.googlecode.com/
PHP | 377 lines | 216 code | 34 blank | 127 comment | 83 complexity | e0ef3ca0609584b4975061149f9db32c MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * CTimestamp class file.
  4. *
  5. * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CTimestamp represents a timestamp.
  12. *
  13. * Part of this class was adapted from the ADOdb Date Library
  14. * {@link http://phplens.com/phpeverywhere/ ADOdb abstraction library}.
  15. * The original source code was released under both BSD and GNU Lesser GPL
  16. * library license, with the following copyright notice:
  17. * Copyright (c) 2000, 2001, 2002, 2003, 2004 John Lim
  18. * All rights reserved.
  19. *
  20. * This class is provided to support UNIX timestamp that is beyond the range
  21. * of 1901-2038 on Unix and1970-2038 on Windows. Except {@link getTimestamp},
  22. * all other methods in this class can work with the extended timestamp range.
  23. * For {@link getTimestamp}, because it is merely a wrapper of
  24. * {@link mktime http://php.net/manual/en/function.mktime.php}, it may still
  25. * be subject to the limit of timestamp range on certain platforms. Please refer
  26. * to the PHP manual for more information.
  27. *
  28. * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
  29. * @version $Id: CTimestamp.php 242 2012-03-29 15:18:01Z mole1230 $
  30. * @package system.utils
  31. * @since 1.0
  32. */
  33. class CTimestamp
  34. {
  35. /**
  36. * Gets day of week, 0 = Sunday,... 6=Saturday.
  37. * Algorithm from PEAR::Date_Calc
  38. * @param integer $year year
  39. * @param integer $month month
  40. * @param integer $day day
  41. * @return integer day of week
  42. */
  43. public static function getDayofWeek($year, $month, $day)
  44. {
  45. /*
  46. Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
  47. proclaimed that from that time onwards 3 days would be dropped from the calendar
  48. every 400 years.
  49. Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
  50. */
  51. if ($year <= 1582)
  52. {
  53. if ($year < 1582 ||
  54. ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15))))
  55. {
  56. $greg_correction = 3;
  57. }
  58. else
  59. {
  60. $greg_correction = 0;
  61. }
  62. }
  63. else
  64. {
  65. $greg_correction = 0;
  66. }
  67. if($month > 2)
  68. $month -= 2;
  69. else
  70. {
  71. $month += 10;
  72. $year--;
  73. }
  74. $day = floor((13 * $month - 1) / 5) +
  75. $day + ($year % 100) +
  76. floor(($year % 100) / 4) +
  77. floor(($year / 100) / 4) - 2 *
  78. floor($year / 100) + 77 + $greg_correction;
  79. return $day - 7 * floor($day / 7);
  80. }
  81. /**
  82. * Checks for leap year, returns true if it is. No 2-digit year check. Also
  83. * handles julian calendar correctly.
  84. * @param integer $year year to check
  85. * @return boolean true if is leap year
  86. */
  87. public static function isLeapYear($year)
  88. {
  89. $year = self::digitCheck($year);
  90. if ($year % 4 != 0)
  91. return false;
  92. if ($year % 400 == 0)
  93. return true;
  94. // if gregorian calendar (>1582), century not-divisible by 400 is not leap
  95. else if ($year > 1582 && $year % 100 == 0 )
  96. return false;
  97. return true;
  98. }
  99. /**
  100. * Fix 2-digit years. Works for any century.
  101. * Assumes that if 2-digit is more than 30 years in future, then previous century.
  102. * @param integer $y year
  103. * @return integer change two digit year into multiple digits
  104. */
  105. protected static function digitCheck($y)
  106. {
  107. if ($y < 100){
  108. $yr = (integer) date("Y");
  109. $century = (integer) ($yr /100);
  110. if ($yr%100 > 50) {
  111. $c1 = $century + 1;
  112. $c0 = $century;
  113. } else {
  114. $c1 = $century;
  115. $c0 = $century - 1;
  116. }
  117. $c1 *= 100;
  118. // if 2-digit year is less than 30 years in future, set it to this century
  119. // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
  120. if (($y + $c1) < $yr+30) $y = $y + $c1;
  121. else $y = $y + $c0*100;
  122. }
  123. return $y;
  124. }
  125. /**
  126. * Returns 4-digit representation of the year.
  127. * @param integer $y year
  128. * @return integer 4-digit representation of the year
  129. */
  130. public static function get4DigitYear($y)
  131. {
  132. return self::digitCheck($y);
  133. }
  134. /**
  135. * @return integer get local time zone offset from GMT
  136. */
  137. public static function getGMTDiff()
  138. {
  139. static $TZ;
  140. if (isset($TZ)) return $TZ;
  141. $TZ = mktime(0,0,0,1,2,1970) - gmmktime(0,0,0,1,2,1970);
  142. return $TZ;
  143. }
  144. /**
  145. * Returns the getdate() array.
  146. * @param integer|boolean $d original date timestamp. False to use the current timestamp.
  147. * @param boolean $fast false to compute the day of the week, default is true
  148. * @param boolean $gmt true to calculate the GMT dates
  149. * @return array an array with date info.
  150. */
  151. public static function getDate($d=false,$fast=false,$gmt=false)
  152. {
  153. if($d===false)
  154. $d=time();
  155. if($gmt)
  156. {
  157. $tz = date_default_timezone_get();
  158. date_default_timezone_set('GMT');
  159. $result = getdate($d);
  160. date_default_timezone_set($tz);
  161. }
  162. else
  163. {
  164. $result = getdate($d);
  165. }
  166. return $result;
  167. }
  168. /**
  169. * Checks to see if the year, month, day are valid combination.
  170. * @param integer $y year
  171. * @param integer $m month
  172. * @param integer $d day
  173. * @return boolean true if valid date, semantic check only.
  174. */
  175. public static function isValidDate($y,$m,$d)
  176. {
  177. return checkdate($m, $d, $y);
  178. }
  179. /**
  180. * Checks to see if the hour, minute and second are valid.
  181. * @param integer $h hour
  182. * @param integer $m minute
  183. * @param integer $s second
  184. * @param boolean $hs24 whether the hours should be 0 through 23 (default) or 1 through 12.
  185. * @return boolean true if valid date, semantic check only.
  186. */
  187. public static function isValidTime($h,$m,$s,$hs24=true)
  188. {
  189. if($hs24 && ($h < 0 || $h > 23) || !$hs24 && ($h < 1 || $h > 12)) return false;
  190. if($m > 59 || $m < 0) return false;
  191. if($s > 59 || $s < 0) return false;
  192. return true;
  193. }
  194. /**
  195. * Formats a timestamp to a date string.
  196. * @param string $fmt format pattern
  197. * @param integer|boolean $d timestamp
  198. * @param boolean $is_gmt whether this is a GMT timestamp
  199. * @return string formatted date based on timestamp $d
  200. */
  201. public static function formatDate($fmt,$d=false,$is_gmt=false)
  202. {
  203. if ($d === false)
  204. return ($is_gmt)? @gmdate($fmt): @date($fmt);
  205. // check if number in 32-bit signed range
  206. if ((abs($d) <= 0x7FFFFFFF))
  207. {
  208. // if windows, must be +ve integer
  209. if ($d >= 0)
  210. return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
  211. }
  212. $_day_power = 86400;
  213. $arr = self::getDate($d,true,$is_gmt);
  214. $year = $arr['year'];
  215. $month = $arr['mon'];
  216. $day = $arr['mday'];
  217. $hour = $arr['hours'];
  218. $min = $arr['minutes'];
  219. $secs = $arr['seconds'];
  220. $max = strlen($fmt);
  221. $dates = '';
  222. /*
  223. at this point, we have the following integer vars to manipulate:
  224. $year, $month, $day, $hour, $min, $secs
  225. */
  226. for ($i=0; $i < $max; $i++)
  227. {
  228. switch($fmt[$i])
  229. {
  230. case 'T': $dates .= date('T');break;
  231. // YEAR
  232. case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
  233. case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
  234. // 4.3.11 uses '04 Jun 2004'
  235. // 4.3.8 uses ' 4 Jun 2004'
  236. $dates .= gmdate('D',$_day_power*(3+self::getDayOfWeek($year,$month,$day))).', '
  237. . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
  238. if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour;
  239. if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
  240. if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
  241. $gmt = self::getGMTDiff();
  242. $dates .= sprintf(' %s%04d',($gmt<=0)?'+':'-',abs($gmt)/36);
  243. break;
  244. case 'Y': $dates .= $year; break;
  245. case 'y': $dates .= substr($year,strlen($year)-2,2); break;
  246. // MONTH
  247. case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
  248. case 'Q': $dates .= ($month+3)>>2; break;
  249. case 'n': $dates .= $month; break;
  250. case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
  251. case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
  252. // DAY
  253. case 't': $dates .= $arr['ndays']; break;
  254. case 'z': $dates .= $arr['yday']; break;
  255. case 'w': $dates .= self::getDayOfWeek($year,$month,$day); break;
  256. case 'l': $dates .= gmdate('l',$_day_power*(3+self::getDayOfWeek($year,$month,$day))); break;
  257. case 'D': $dates .= gmdate('D',$_day_power*(3+self::getDayOfWeek($year,$month,$day))); break;
  258. case 'j': $dates .= $day; break;
  259. case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
  260. case 'S':
  261. $d10 = $day % 10;
  262. if ($d10 == 1) $dates .= 'st';
  263. else if ($d10 == 2 && $day != 12) $dates .= 'nd';
  264. else if ($d10 == 3) $dates .= 'rd';
  265. else $dates .= 'th';
  266. break;
  267. // HOUR
  268. case 'Z':
  269. $dates .= ($is_gmt) ? 0 : -self::getGMTDiff(); break;
  270. case 'O':
  271. $gmt = ($is_gmt) ? 0 : self::getGMTDiff();
  272. $dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36);
  273. break;
  274. case 'H':
  275. if ($hour < 10) $dates .= '0'.$hour;
  276. else $dates .= $hour;
  277. break;
  278. case 'h':
  279. if ($hour > 12) $hh = $hour - 12;
  280. else {
  281. if ($hour == 0) $hh = '12';
  282. else $hh = $hour;
  283. }
  284. if ($hh < 10) $dates .= '0'.$hh;
  285. else $dates .= $hh;
  286. break;
  287. case 'G':
  288. $dates .= $hour;
  289. break;
  290. case 'g':
  291. if ($hour > 12) $hh = $hour - 12;
  292. else {
  293. if ($hour == 0) $hh = '12';
  294. else $hh = $hour;
  295. }
  296. $dates .= $hh;
  297. break;
  298. // MINUTES
  299. case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
  300. // SECONDS
  301. case 'U': $dates .= $d; break;
  302. case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
  303. // AM/PM
  304. // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
  305. case 'a':
  306. if ($hour>=12) $dates .= 'pm';
  307. else $dates .= 'am';
  308. break;
  309. case 'A':
  310. if ($hour>=12) $dates .= 'PM';
  311. else $dates .= 'AM';
  312. break;
  313. default:
  314. $dates .= $fmt[$i]; break;
  315. // ESCAPE
  316. case "\\":
  317. $i++;
  318. if ($i < $max) $dates .= $fmt[$i];
  319. break;
  320. }
  321. }
  322. return $dates;
  323. }
  324. /**
  325. * Generates a timestamp.
  326. * This is the same as the PHP function {@link mktime http://php.net/manual/en/function.mktime.php}.
  327. * @param integer $hr hour
  328. * @param integer $min minute
  329. * @param integer $sec second
  330. * @param integer|boolean $mon month
  331. * @param integer|boolean $day day
  332. * @param integer|boolean $year year
  333. * @param boolean $is_gmt whether this is GMT time. If true, gmmktime() will be used.
  334. * @return integer|float a timestamp given a local time.
  335. */
  336. public static function getTimestamp($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_gmt=false)
  337. {
  338. if ($mon === false)
  339. return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
  340. return $is_gmt ? @gmmktime($hr,$min,$sec,$mon,$day,$year) : @mktime($hr,$min,$sec,$mon,$day,$year);
  341. }
  342. }