date.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <?php
  2. /**
  3. * date.php
  4. *
  5. * Copyright (c) 1999-2004 The SquirrelMail Project Team
  6. * Licensed under the GNU GPL. For full terms see the file COPYING.
  7. *
  8. * Takes a date and parses it into a usable format. The form that a
  9. * date SHOULD arrive in is:
  10. * <Tue,> 29 Jun 1999 09:52:11 -0500 (EDT)
  11. * (as specified in RFC 822) -- 'Tue' is optional
  12. *
  13. * @version $Id$
  14. * @package squirrelmail
  15. */
  16. /** Load up some useful constants */
  17. require_once(SM_PATH . 'functions/constants.php');
  18. /**
  19. * Corrects a time stamp to be the local time.
  20. *
  21. * @param int stamp the timestamp to adjust
  22. * @param string tzc the timezone correction
  23. * @return int the corrected timestamp
  24. */
  25. function getGMTSeconds($stamp, $tzc) {
  26. /* date couldn't be parsed */
  27. if ($stamp == -1) {
  28. return -1;
  29. }
  30. /* timezone correction, expressed as `shhmm' */
  31. switch($tzc)
  32. {
  33. case 'Pacific':
  34. case 'PST':
  35. $tzc = '-0800';
  36. break;
  37. case 'Mountain':
  38. case 'MST':
  39. case 'PDT':
  40. $tzc = '-0700';
  41. break;
  42. case 'Central':
  43. case 'CST':
  44. case 'MDT':
  45. $tzc = '-0600';
  46. break;
  47. case 'Eastern':
  48. case 'EST':
  49. case 'CDT':
  50. $tzc = '-0500';
  51. break;
  52. case 'EDT':
  53. $tzc = '-0400';
  54. break;
  55. case 'GMT':
  56. $tzc = '+0000';
  57. break;
  58. case 'BST':
  59. case 'MET':
  60. case 'CET':
  61. $tzc = '+0100';
  62. break;
  63. case 'EET':
  64. case 'IST':
  65. case 'MET DST':
  66. case 'METDST':
  67. $tzc = '+0200';
  68. break;
  69. case 'HKT':
  70. $tzc = '+0800';
  71. break;
  72. case 'JST':
  73. case 'KST':
  74. $tzc = '+0900';
  75. break;
  76. }
  77. $neg = false;
  78. if (substr($tzc, 0, 1) == '-') {
  79. $neg = true;
  80. } else if (substr($tzc, 0, 1) != '+') {
  81. $tzc = '+'.$tzc;
  82. }
  83. $hh = substr($tzc,1,2);
  84. $mm = substr($tzc,3,2);
  85. $iTzc = ($hh * 60 + $mm) * 60;
  86. if ($neg) $iTzc = -1 * (int) $iTzc;
  87. /* stamp in gmt */
  88. $stamp -= $iTzc;
  89. /** now find what the server is at **/
  90. $current = date('Z', time());
  91. /* stamp in local timezone */
  92. $stamp += $current;
  93. return $stamp;
  94. }
  95. /**
  96. * Returns the (localized) string for a given day number.
  97. * Switch system has been intentionaly chosen for the
  98. * internationalization of month and day names. The reason
  99. * is to make sure that _("") strings will go into the
  100. * main po.
  101. *
  102. * @param int day_number the day number
  103. * @return string the day in human readable form
  104. */
  105. function getDayName( $day_number ) {
  106. switch( $day_number ) {
  107. case 0:
  108. $ret = _("Sunday");
  109. break;
  110. case 1:
  111. $ret = _("Monday");
  112. break;
  113. case 2:
  114. $ret = _("Tuesday");
  115. break;
  116. case 3:
  117. $ret = _("Wednesday");
  118. break;
  119. case 4:
  120. $ret = _("Thursday");
  121. break;
  122. case 5:
  123. $ret = _("Friday");
  124. break;
  125. case 6:
  126. $ret = _("Saturday");
  127. break;
  128. default:
  129. $ret = '';
  130. }
  131. return( $ret );
  132. }
  133. /**
  134. * Like getDayName, but returns the short form
  135. * @param int day_number the day number
  136. * @return string the day in short human readable form
  137. */
  138. function getDayAbrv( $day_number ) {
  139. switch( $day_number ) {
  140. case 0:
  141. $ret = _("Sun");
  142. break;
  143. case 1:
  144. $ret = _("Mon");
  145. break;
  146. case 2:
  147. $ret = _("Tue");
  148. break;
  149. case 3:
  150. $ret = _("Wed");
  151. break;
  152. case 4:
  153. $ret = _("Thu");
  154. break;
  155. case 5:
  156. $ret = _("Fri");
  157. break;
  158. case 6:
  159. $ret = _("Sat");
  160. break;
  161. default:
  162. $ret = '';
  163. }
  164. return( $ret );
  165. }
  166. /**
  167. * Returns the (localized) string for a given month number.
  168. *
  169. * @param string month_number the month number (01..12)
  170. * @return string the month name in human readable form
  171. */
  172. function getMonthName( $month_number ) {
  173. switch( $month_number ) {
  174. case '01':
  175. $ret = _("January");
  176. break;
  177. case '02':
  178. $ret = _("February");
  179. break;
  180. case '03':
  181. $ret = _("March");
  182. break;
  183. case '04':
  184. $ret = _("April");
  185. break;
  186. case '05':
  187. $ret = _("May");
  188. break;
  189. case '06':
  190. $ret = _("June");
  191. break;
  192. case '07':
  193. $ret = _("July");
  194. break;
  195. case '08':
  196. $ret = _("August");
  197. break;
  198. case '09':
  199. $ret = _("September");
  200. break;
  201. case '10':
  202. $ret = _("October");
  203. break;
  204. case '11':
  205. $ret = _("November");
  206. break;
  207. case '12':
  208. $ret = _("December");
  209. break;
  210. default:
  211. $ret = '';
  212. }
  213. return( $ret );
  214. }
  215. /**
  216. * Returns the (localized) string for a given month number,
  217. * short representation.
  218. *
  219. * @param string month_number the month number (01..12)
  220. * @return string the shortened month in human readable form
  221. */
  222. function getMonthAbrv( $month_number ) {
  223. switch( $month_number ) {
  224. case '01':
  225. $ret = _("Jan");
  226. break;
  227. case '02':
  228. $ret = _("Feb");
  229. break;
  230. case '03':
  231. $ret = _("Mar");
  232. break;
  233. case '04':
  234. $ret = _("Apr");
  235. break;
  236. case '05':
  237. $ret = _("Ma&#121;");
  238. break;
  239. case '06':
  240. $ret = _("Jun");
  241. break;
  242. case '07':
  243. $ret = _("Jul");
  244. break;
  245. case '08':
  246. $ret = _("Aug");
  247. break;
  248. case '09':
  249. $ret = _("Sep");
  250. break;
  251. case '10':
  252. $ret = _("Oct");
  253. break;
  254. case '11':
  255. $ret = _("Nov");
  256. break;
  257. case '12':
  258. $ret = _("Dec");
  259. break;
  260. default:
  261. $ret = '';
  262. }
  263. return( $ret );
  264. }
  265. /**
  266. * Returns the localized representation of the date/time.
  267. *
  268. * @param string date_format The format for the date, like the input for the PHP date() function.
  269. * @param int stamp the timestamp to convert
  270. * @return string a full date representation
  271. */
  272. function date_intl( $date_format, $stamp ) {
  273. $ret = str_replace( array('D','F','l','M'), array('$1','$2','$3','$4'), $date_format );
  274. // to reduce the date calls we retrieve m and w in the same call
  275. $ret = date('w#m#'. $ret, $stamp );
  276. // extract day and month in order to replace later by intl day and month
  277. $aParts = explode('#',$ret);
  278. $ret = str_replace(array('$1','$4','$2','$3',), array(getDayAbrv($aParts[0]),
  279. getMonthAbrv($aParts[1]),
  280. getMonthName($aParts[1]),
  281. getDayName($aParts[0])),
  282. $aParts[2]);
  283. return( $ret );
  284. }
  285. /**
  286. * This returns a date of the format "Wed, Oct 29, 2003 9:52 am",
  287. * or the same in 24H format (depending on the user's settings),
  288. * and taking localization into accout.
  289. *
  290. * @param int stamp the timestamp
  291. * @return string the long date string
  292. */
  293. function getLongDateString( $stamp ) {
  294. global $hour_format;
  295. if ($stamp == -1) {
  296. return '';
  297. }
  298. if ( $hour_format == SMPREF_TIME_12HR ) {
  299. $date_format = _("D, F j, Y g:i a");
  300. } else {
  301. $date_format = _("D, F j, Y G:i");
  302. }
  303. return( date_intl( $date_format, $stamp ) );
  304. }
  305. /**
  306. * Returns a short representation of the date,
  307. * taking timezones and localization into account.
  308. * Depending on user's settings, this string can be
  309. * of the form: "14:23" or "Jun 14, 2003" depending
  310. * on whether the stamp is "today" or not.
  311. *
  312. * @param int stamp the timestamp
  313. * @return string the date string
  314. */
  315. function getDateString( $stamp ) {
  316. global $invert_time, $hour_format, $show_full_date;
  317. if ( $stamp == -1 ) {
  318. return '';
  319. }
  320. $now = time();
  321. $dateZ = date('Z', $now );
  322. // FIXME: isn't this obsolete and introduced as a terrible workaround
  323. // for bugs at other places which are fixed a long time ago?
  324. if ($invert_time) {
  325. $dateZ = - $dateZ;
  326. }
  327. $midnight = $now - ($now % 86400) - $dateZ;
  328. $nextmid = $midnight + 86400 - $dateZ;
  329. if (($show_full_date == 1) || ($nextmid < $stamp)) {
  330. $date_format = _("M j, Y");
  331. } else if ($midnight < $stamp) {
  332. /* Today */
  333. if ( $hour_format == SMPREF_TIME_12HR ) {
  334. $date_format = _("g:i a");
  335. } else {
  336. $date_format = _("G:i");
  337. }
  338. } else if ($midnight - 518400 < $stamp) {
  339. /* This week */
  340. if ( $hour_format == SMPREF_TIME_12HR ) {
  341. $date_format = _("D, g:i a");
  342. } else {
  343. $date_format = _("D, G:i");
  344. }
  345. } else {
  346. /* before this week */
  347. $date_format = _("M j, Y");
  348. }
  349. return( date_intl( $date_format, $stamp ) );
  350. }
  351. /**
  352. * Decodes a RFC 822 Date-header into a timestamp
  353. *
  354. * @param array dateParts the Date-header split by whitespace
  355. * @return int the timestamp calculated from the header
  356. */
  357. function getTimeStamp($dateParts) {
  358. /** $dateParts[0] == <day of week> Mon, Tue, Wed
  359. ** $dateParts[1] == <day of month> 23
  360. ** $dateParts[2] == <month> Jan, Feb, Mar
  361. ** $dateParts[3] == <year> 1999
  362. ** $dateParts[4] == <time> 18:54:23 (HH:MM:SS)
  363. ** $dateParts[5] == <from GMT> +0100
  364. ** $dateParts[6] == <zone> (EDT)
  365. **
  366. ** NOTE: In RFC 822, it states that <day of week> is optional.
  367. ** In that case, dateParts[0] would be the <day of month>
  368. ** and everything would be bumped up one.
  369. **/
  370. /*
  371. * Simply check to see if the first element in the dateParts
  372. * array is an integer or not.
  373. * Since the day of week is optional, this check is needed.
  374. */
  375. if (count($dateParts) <2) {
  376. return -1;
  377. } else if (count($dateParts) ==3) {
  378. if (substr_count($dateParts[0],'-') == 2 &&
  379. substr_count($dateParts[1],':') == 2) {
  380. // dd-Month-yyyy 23:19:05 +0200
  381. // redefine the date
  382. $aDate = explode('-',$dateParts[0]);
  383. $newDate = array($aDate[0],$aDate[1],$aDate[2],$dateParts[1],$dateParts[2]);
  384. $dateParts = $newDate;
  385. }
  386. }
  387. /* remove day of week */
  388. if (!is_numeric(trim($dateParts[0]))) {
  389. $dataParts = array_shift($dateParts);
  390. }
  391. /* calculate timestamp separated from the zone and obs-zone */
  392. $stamp = strtotime(implode (' ', array_splice ($dateParts,0,4)));
  393. if (!isset($dateParts[0])) {
  394. $dateParts[0] = '+0000';
  395. }
  396. if (!preg_match('/^[+-]{1}[0-9]{4}$/',$dateParts[0])) {
  397. /* zone in obs-zone format */
  398. if (preg_match('/\((.+)\)/',$dateParts[0],$regs)) {
  399. $obs_zone = $regs[1];
  400. } else {
  401. $obs_zone = $dateParts[0];
  402. }
  403. return getGMTSeconds($stamp, $obs_zone);
  404. } else {
  405. return getGMTSeconds($stamp, $dateParts[0]);
  406. }
  407. }
  408. /* I use this function for profiling. Should never be called in
  409. actual versions of squirrelmail released to public. */
  410. /*
  411. function getmicrotime() {
  412. $mtime = microtime();
  413. $mtime = explode(' ',$mtime);
  414. $mtime = $mtime[1] + $mtime[0];
  415. return ($mtime);
  416. }
  417. */
  418. ?>