PageRenderTime 227ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/system/core/core.localize.php

https://github.com/danboy/Croissierd
PHP | 1114 lines | 674 code | 248 blank | 192 comment | 153 complexity | 8ae8e3dcb67482fafb1504f316a632c2 MD5 | raw file
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010 EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/docs/license.html
  13. =====================================================
  14. File: core.localize.php
  15. -----------------------------------------------------
  16. Purpose: Date/time and localization functions
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Localize {
  24. var $server_now = ''; // Local server time
  25. var $now = ''; // Local server time as GMT
  26. var $ctz = 0; // Current user's timezone setting
  27. var $zones = array();
  28. var $cached = array();
  29. var $format = array('DATE_ATOM' => '%Y-%m-%dT%H:%i:%s%Q',
  30. 'DATE_COOKIE' => '%l, %d-%M-%y %H:%i:%s UTC',
  31. 'DATE_ISO8601' => '%Y-%m-%dT%H:%i:%s%O',
  32. 'DATE_RFC822' => '%D, %d %M %y %H:%i:%s %O',
  33. 'DATE_RFC850' => '%l, %d-%M-%y %H:%m:%i UTC',
  34. 'DATE_RFC1036' => '%D, %d %M %y %H:%i:%s %O',
  35. 'DATE_RFC1123' => '%D, %d %M %Y %H:%i:%s %O',
  36. 'DATE_RFC2822' => '%D, %d %M %Y %H:%i:%s %O',
  37. 'DATE_RSS' => '%D, %d %M %Y %H:%i:%s %O',
  38. 'DATE_W3C' => '%Y-%m-%dT%H:%i:%s%Q'
  39. );
  40. /** -------------------------------------
  41. /** Constructor
  42. /** -------------------------------------*/
  43. // Fetch the current local server time and convert it to GMT
  44. function Localize()
  45. {
  46. $this->server_now = time();
  47. $this->now = $this->set_gmt($this->server_now);
  48. $this->zones = $this->zones();
  49. }
  50. /* END */
  51. /** -------------------------------------
  52. /** Set GMT time
  53. /** -------------------------------------*/
  54. // Takes a Unix timestamp as input and returns it as GMT
  55. function set_gmt($now = '')
  56. {
  57. if ($now == '')
  58. {
  59. $now = time();
  60. }
  61. $time = @mktime( gmdate("H", $now),
  62. gmdate("i", $now),
  63. gmdate("s", $now),
  64. gmdate("m", $now),
  65. gmdate("d", $now),
  66. gmdate("Y", $now),
  67. -1 // this must be explicitly set or some FreeBSD servers behave erratically
  68. );
  69. // mktime() has a bug that causes it to fail during the DST "spring forward gap"
  70. // when clocks are offset an hour forward (around April 4). Instead of returning a valid
  71. // timestamp, it returns -1. Basically, mktime() gets caught in purgatory, not
  72. // sure if DST is active or not. As a work-around for this we'll test for "-1",
  73. // and if present, return the current time. This is not a great solution, as this time
  74. // may not be what the user intended, but it's preferable than storing -1 as the timestamp,
  75. // which correlates to: 1969-12-31 16:00:00.
  76. if ($time == -1)
  77. {
  78. return $this->set_gmt();
  79. }
  80. else
  81. {
  82. return $time;
  83. }
  84. }
  85. /* END */
  86. /** ---------------------------------------------
  87. /** Convert a MySQL timestamp to GMT
  88. /** ---------------------------------------------*/
  89. function timestamp_to_gmt($str = '')
  90. {
  91. // We'll remove certain characters for backward compatibility
  92. // since the formatting changed with MySQL 4.1
  93. // YYYY-MM-DD HH:MM:SS
  94. $str = str_replace('-', '', $str);
  95. $str = str_replace(':', '', $str);
  96. $str = str_replace(' ', '', $str);
  97. // YYYYMMDDHHMMSS
  98. return $this->set_gmt( mktime( substr($str,8,2),
  99. substr($str,10,2),
  100. substr($str,12,2),
  101. substr($str,4,2),
  102. substr($str,6,2),
  103. substr($str,0,4)
  104. )
  105. );
  106. }
  107. /* END */
  108. /** --------------------------------------------
  109. /** Set localized time
  110. /** --------------------------------------------*/
  111. // Converts GMT time to the localized values of the current logged-in user
  112. function set_localized_time($now = '', $timezone = '', $dst = '')
  113. {
  114. global $PREFS, $SESS;
  115. if ($now == '')
  116. {
  117. $now = $this->now;
  118. }
  119. // This lets us use a different timezone then the logged in user to calculate a time.
  120. // Right now we only use this to show the local time of other users
  121. if ($timezone == '')
  122. {
  123. $timezone = $SESS->userdata['timezone'];
  124. }
  125. // If the current user has not set localization preferences
  126. // we'll instead use the master server settings
  127. if ($timezone == '')
  128. {
  129. return $this->set_server_time($now);
  130. }
  131. $now += $this->zones[$timezone] * 3600;
  132. if ($dst == '')
  133. {
  134. $dst = $SESS->userdata('daylight_savings');
  135. }
  136. if ($dst == 'y')
  137. {
  138. $now += 3600;
  139. }
  140. return $this->set_server_offset($now);
  141. }
  142. /* END */
  143. /** --------------------------------------------
  144. /** Set localized server time
  145. /** --------------------------------------------*/
  146. // Converts GMT time to the localized server timezone
  147. function set_server_time($now = '')
  148. {
  149. global $PREFS;
  150. if ($now == '')
  151. {
  152. $now = $this->now;
  153. }
  154. if ($tz = $PREFS->ini('server_timezone'))
  155. {
  156. $now += $this->zones[$tz] * 3600;
  157. }
  158. if ($PREFS->ini('daylight_savings') == 'y')
  159. {
  160. $now += 3600;
  161. }
  162. $now = $this->set_server_offset($now);
  163. return $now;
  164. }
  165. /* END */
  166. /** --------------------------------------------
  167. /** Set server offset
  168. /** --------------------------------------------*/
  169. // Takes a Unix timestamp as input and adds/subtracts the number of
  170. // minutes specified in the master server time offset preference
  171. // The optional second parameter lets us reverse the offset (positive number becomes negative)
  172. // We use the second paramter with set_localized_offset()
  173. function set_server_offset($time, $reverse = 0)
  174. {
  175. global $PREFS;
  176. $offset = ( ! $PREFS->ini('server_offset')) ? 0 : $PREFS->ini('server_offset') * 60;
  177. if ($offset == 0)
  178. {
  179. return $time;
  180. }
  181. if ($reverse == 1)
  182. {
  183. $offset = $offset * -1;
  184. }
  185. $time += $offset;
  186. return $time;
  187. }
  188. /* END */
  189. /** --------------------------------------------
  190. /** Set localized offset
  191. /** --------------------------------------------*/
  192. // This function lets us calculate the time difference between the
  193. // timezone of the current user and the timezone of the server hosting
  194. // the site. It solves a dilemma we face when using functions like mktime()
  195. // which base their output on the server's timezone. When a weblog entry is
  196. // submitted, the entry date is converted to a Unix timestamp. But since
  197. // the user submitting the entry might not be in the same timezone as the
  198. // server we need to offset the timestamp to reflect this difference.
  199. function set_localized_offset()
  200. {
  201. global $PREFS, $SESS;
  202. $offset = 0;
  203. if ($SESS->userdata['timezone'] == '')
  204. {
  205. if ($tz = $PREFS->ini('server_timezone'))
  206. {
  207. $offset += $this->zones[$tz];
  208. }
  209. if ($PREFS->ini('daylight_savings') == 'y')
  210. {
  211. $offset += 1;
  212. }
  213. }
  214. else
  215. {
  216. $offset += $this->zones[$SESS->userdata['timezone']];
  217. if ($SESS->userdata['daylight_savings'] == 'y')
  218. {
  219. $offset += 1;
  220. }
  221. }
  222. // Grab local time
  223. $time = $this->server_now;
  224. // Determine the number of seconds between the local time and GMT
  225. $time -= $this->now;
  226. // Offset this number based on the server offset (if it exists)
  227. $time = $this->set_server_offset($time, 1);
  228. // Divide by 3600, making our offset into hours
  229. $time = $time/3600;
  230. // add or subtract it from our timezone offset
  231. $offset -= $time;
  232. // Multiply by -1 to invert the value (positive becomes negative and vice versa)
  233. $offset = $offset * -1;
  234. // Convert it to seconds
  235. if ($offset != 0)
  236. $offset = $offset * (60 * 60);
  237. return $offset;
  238. }
  239. /* END */
  240. /** -------------------------------------
  241. /** Human-readable time
  242. /** -------------------------------------*/
  243. // Formats Unix/GMT timestamp to the following format: 2003-08-21 11:35 PM
  244. // Will also switch to Euro time based on the user preference
  245. function set_human_time($now = '', $localize = TRUE, $seconds = FALSE)
  246. {
  247. global $PREFS, $SESS;
  248. /* -------------------------------------------
  249. /* Hidden Configuration Variable
  250. /* - include_seconds => If set to 'y',
  251. /* then we include the seconds on our human time.
  252. /* -------------------------------------------*/
  253. if (func_num_args() != 3 && $PREFS->ini('include_seconds') == 'y')
  254. {
  255. $seconds = TRUE;
  256. }
  257. $fmt = ($SESS->userdata['time_format'] != '') ? $SESS->userdata['time_format'] : $PREFS->ini('time_format');
  258. if ($localize)
  259. {
  260. $now = $this->set_localized_time($now);
  261. }
  262. $r = date('Y', $now).'-'.date('m', $now).'-'.date('d', $now).' ';
  263. if ($fmt == 'us')
  264. {
  265. $r .= date('h', $now).':'.date('i', $now);
  266. }
  267. else
  268. {
  269. $r .= date('H', $now).':'.date('i', $now);
  270. }
  271. if ($seconds)
  272. {
  273. $r .= ':'.date('s', $now);
  274. }
  275. if ($fmt == 'us')
  276. {
  277. $r .= ' '.date('A', $now);
  278. }
  279. return $r;
  280. }
  281. /* END */
  282. /** -------------------------------------------------------
  283. /** Convert "human" date to GMT
  284. /** -------------------------------------------------------*/
  285. // Converts the human-readable date used in the weblog entry
  286. // submission page back to Unix/GMT
  287. function convert_human_date_to_gmt($datestr = '')
  288. {
  289. global $LANG, $SESS, $PREFS;
  290. if ($datestr == '')
  291. return false;
  292. $datestr = trim($datestr);
  293. $datestr = preg_replace("/\040+/", "\040", $datestr);
  294. if ( ! preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))
  295. {
  296. return $LANG->line('invalid_date_formatting');
  297. }
  298. $split = preg_split("/\040/", $datestr);
  299. $ex = explode("-", $split['0']);
  300. $year = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0'];
  301. $month = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];
  302. $day = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];
  303. $ex = explode(":", $split['1']);
  304. $hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0'];
  305. $min = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];
  306. // I'll explain later
  307. $fib_seconds = FALSE;
  308. if (isset($ex['2']) AND preg_match("/[0-9]{1,2}/", $ex['2']))
  309. {
  310. $sec = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];
  311. }
  312. else
  313. {
  314. // Unless specified, seconds get set to zero.
  315. // $sec = '00';
  316. // The above doesn't make sense to me, and can cause entries submitted within the same
  317. // minute to have identical timestamps, so I'm reverting to an older behavior - D'Jones
  318. // *********************************************************************************************
  319. // I now see what Paul was initially avoiding. So, here's the dealio and how we'll address it:
  320. // Since the seconds were not specified, we're going to fib and roll back one second, otherwise
  321. // the submitted entry will be considered to not be < $LOC->now and will not be displayed on
  322. // the page request that creates it, a common scenario when submitting entries via a SAEF.
  323. // So we'll set a flag, and adjust the time by one second after the timestamp is generated.
  324. // If we do it here, we'd have to step backwards through minutes and hours and days etc. to
  325. // check if each needs to roll back, for dates like January 1, 1990 12:00:00
  326. $sec = date('s', $this->now);
  327. $fib_seconds = TRUE;
  328. }
  329. if (isset($split['2']))
  330. {
  331. $ampm = strtolower($split['2']);
  332. if (substr($ampm, 0, 1) == 'p' AND $hour < 12)
  333. $hour = $hour + 12;
  334. if (substr($ampm, 0, 1) == 'a' AND $hour == 12)
  335. $hour = '00';
  336. if (strlen($hour) == 1)
  337. $hour = '0'.$hour;
  338. }
  339. if ($year < 1902 || $year > 2037)
  340. {
  341. return $LANG->line('date_outside_of_range');
  342. }
  343. $time = $this->set_gmt(mktime($hour, $min, $sec, $month, $day, $year));
  344. // Are we fibbing?
  345. if ($fib_seconds === TRUE)
  346. {
  347. $time = $time - 1;
  348. }
  349. // Offset the time by one hour if the user is submitting a date
  350. // in the future or past so that it is no longer in the same
  351. // Daylight saving time.
  352. if (date("I", $this->now))
  353. {
  354. if ( ! date("I", $time))
  355. {
  356. $time -= 3600;
  357. }
  358. }
  359. else
  360. {
  361. if (date("I", $time))
  362. {
  363. $time += 3600;
  364. }
  365. }
  366. $time += $this->set_localized_offset();
  367. return $time;
  368. }
  369. /* END */
  370. /** --------------------------------------------
  371. /** Simple Offset
  372. /** --------------------------------------------*/
  373. // This allows a timestamp to be offset by the submitted timezone.
  374. // Currently this is only used in the PUBLISH page
  375. function simpl_offset($time = '', $timezone = '')
  376. {
  377. global $SESS;
  378. $time += $this->zones[$timezone] * 3600;
  379. if ($SESS->userdata('daylight_savings') == 'y')
  380. {
  381. $time += 3600;
  382. }
  383. return $time;
  384. }
  385. /* END */
  386. /** --------------------------------------------
  387. /** Offset Entry DST
  388. /** --------------------------------------------*/
  389. // This adds/subtracts an hour if the submitted entry
  390. // has the "honor DST setting" clicked
  391. function offset_entry_dst($time = '', $dst_enabled = '', $add_time = TRUE)
  392. {
  393. global $SESS, $PREFS;
  394. if ($PREFS->ini('honor_entry_dst') == 'y')
  395. {
  396. if ($dst_enabled == 'n' AND $SESS->userdata('daylight_savings') == 'y')
  397. {
  398. if ($add_time == TRUE)
  399. $time += 3600;
  400. else
  401. $time -= 3600;
  402. }
  403. elseif ($dst_enabled == 'y' AND $SESS->userdata('daylight_savings') == 'n')
  404. {
  405. if ($add_time == TRUE)
  406. $time -= 3600;
  407. else
  408. $time += 3600;
  409. }
  410. }
  411. return $time;
  412. }
  413. /* END */
  414. /** ----------------------------------
  415. /** Format timespan
  416. /** ----------------------------------*/
  417. // Returns a span of seconds in this format: 10 days 14 hours 36 minutes 47 seconds
  418. function format_timespan($seconds = '')
  419. {
  420. global $LANG;
  421. // things can get really screwy if a negative number is passed, which can happen
  422. // in very rare load-balanced environments when the web servers' are not in
  423. // perfect sync with one another
  424. $seconds = abs($seconds);
  425. if ($seconds == '')
  426. $seconds = 1;
  427. $str = '';
  428. $years = floor($seconds / 31536000);
  429. if ($years > 0)
  430. {
  431. $str .= $years.' '.$LANG->line(($years > 1) ? 'years' : 'year').', ';
  432. }
  433. $seconds -= $years * 31536000;
  434. $months = floor($seconds / 2628000);
  435. if ($years > 0 || $months > 0)
  436. {
  437. if ($months > 0)
  438. {
  439. $str .= $months.' '.$LANG->line(($months > 1) ? 'months' : 'month').', ';
  440. }
  441. $seconds -= $months * 2628000;
  442. }
  443. $weeks = floor($seconds / 604800);
  444. if ($years > 0 || $months > 0 || $weeks > 0)
  445. {
  446. if ($weeks > 0)
  447. {
  448. $str .= $weeks.' '.$LANG->line(($weeks > 1) ? 'weeks' : 'week').', ';
  449. }
  450. $seconds -= $weeks * 604800;
  451. }
  452. $days = floor($seconds / 86400);
  453. if ($months > 0 || $weeks > 0 || $days > 0)
  454. {
  455. if ($days > 0)
  456. {
  457. $str .= $days.' '.$LANG->line(($days > 1) ? 'days' : 'day').', ';
  458. }
  459. $seconds -= $days * 86400;
  460. }
  461. $hours = floor($seconds / 3600);
  462. if ($days > 0 || $hours > 0)
  463. {
  464. if ($hours > 0)
  465. {
  466. $str .= $hours.' '.$LANG->line(($hours > 1) ? 'hours' : 'hour').', ';
  467. }
  468. $seconds -= $hours * 3600;
  469. }
  470. $minutes = floor($seconds / 60);
  471. if ($days > 0 || $hours > 0 || $minutes > 0)
  472. {
  473. if ($minutes > 0)
  474. {
  475. $str .= $minutes.' '.$LANG->line(($minutes > 1) ? 'minutes' : 'minute').', ';
  476. }
  477. $seconds -= $minutes * 60;
  478. }
  479. if ($str == '')
  480. {
  481. $str .= $seconds.' '.$LANG->line(($seconds > 1) ? 'seconds' : 'second').', ';
  482. }
  483. $str = substr(trim($str), 0, -1);
  484. return $str;
  485. }
  486. /* END */
  487. /** -------------------------------------------------
  488. /** Fetch Date Params (via template parser)
  489. /** -------------------------------------------------*/
  490. function fetch_date_params($datestr = '')
  491. {
  492. if ($datestr == '')
  493. return;
  494. if ( ! preg_match_all("/(%\S)/", $datestr, $matches))
  495. return;
  496. return $matches['1'];
  497. }
  498. /* END */
  499. /** -------------------------------------------------
  500. /** Decode date string (via template parser)
  501. /** -------------------------------------------------*/
  502. // This function takes a string containing text and
  503. // date codes and extracts only the codes. Then,
  504. // the codes are converted to their actual timestamp
  505. // values and the string is reassembled.
  506. function decode_date($datestr = '', $unixtime = '', $localize = TRUE)
  507. {
  508. $prelocalized = FALSE;
  509. if ($datestr == '')
  510. return;
  511. if ($unixtime == 0)
  512. return '';
  513. if ( ! preg_match_all("/(%\S)/", $datestr, $matches))
  514. return;
  515. if ($localize === TRUE)
  516. {
  517. $unixtime = $this->set_localized_time($unixtime);
  518. $prelocalized = TRUE;
  519. }
  520. foreach ($matches['1'] as $val)
  521. {
  522. $datestr = str_replace($val, $this->convert_timestamp($val, $unixtime, FALSE, $prelocalized), $datestr);
  523. }
  524. return $datestr;
  525. }
  526. /* END */
  527. /** -------------------------------------
  528. /** Localize month name
  529. /** -------------------------------------*/
  530. // Helper function used to translate month names.
  531. function localize_month($month = '')
  532. {
  533. $months = array(
  534. '01' => array('Jan', 'January'),
  535. '02' => array('Feb', 'February'),
  536. '03' => array('Mar', 'March'),
  537. '04' => array('Apr', 'April'),
  538. '05' => array('May', 'May_l'),
  539. '06' => array('Jun', 'June'),
  540. '07' => array('Jul', 'July'),
  541. '08' => array('Aug', 'August'),
  542. '09' => array('Sep', 'September'),
  543. '10' => array('Oct', 'October'),
  544. '11' => array('Nov', 'November'),
  545. '12' => array('Dec', 'December')
  546. );
  547. if (isset($months[$month]))
  548. {
  549. return $months[$month];
  550. }
  551. }
  552. /* END */
  553. /** -------------------------------------
  554. /** Convert timestamp codes
  555. /** -------------------------------------*/
  556. // All text codes are converted to the user-specified language.
  557. function convert_timestamp($which = '', $time = '', $localize = TRUE, $prelocalized = FALSE)
  558. {
  559. global $LANG, $SESS, $TMPL;
  560. if ($which == '')
  561. return;
  562. $localized_tz = ($prelocalized == TRUE) ? TRUE : $localize;
  563. $translate = (is_object($TMPL) && $TMPL->template_type == 'rss') ? FALSE : TRUE;
  564. if ($this->ctz == 0)
  565. {
  566. $this->ctz = $this->set_localized_timezone();
  567. }
  568. $time = ($localize == TRUE) ? $this->set_localized_time($time) : $time;
  569. $may = ($which == '%F' AND date('F', $time) == 'May') ? date('F', $time).'_l' : date('F', $time);
  570. if (isset($this->cached[$time][$which]))
  571. {
  572. return $this->cached[$time][$which];
  573. }
  574. switch ($which)
  575. {
  576. case '%a': $var = ($translate === FALSE) ? date('a', $time) : $LANG->line(date('a', $time)); // am/pm
  577. break;
  578. case '%A': $var = ($translate === FALSE) ? date('A', $time) : $LANG->line(date('A', $time)); // AM/PM
  579. break;
  580. case '%B': $var = date('B', $time);
  581. break;
  582. case '%d': $var = date('d', $time);
  583. break;
  584. case '%D': $var = ($translate === FALSE) ? date('D', $time) : $LANG->line(date('D', $time)); // Mon, Tues
  585. break;
  586. case '%F': $var = ($translate === FALSE) ? date('F', $time) : $LANG->line($may); // January, February
  587. break;
  588. case '%g': $var = date('g', $time);
  589. break;
  590. case '%G': $var = date('G', $time);
  591. break;
  592. case '%h': $var = date('h', $time);
  593. break;
  594. case '%H': $var = date('H', $time);
  595. break;
  596. case '%i': $var = date('i', $time);
  597. break;
  598. case '%I': $var = ($localized_tz === TRUE) ? date('I', $time) : gmdate('I', $time);
  599. break;
  600. case '%j': $var = date('j', $time);
  601. break;
  602. case '%l': $var = ($translate === FALSE) ? date('l', $time) : $LANG->line(date('l', $time)); // Monday, Tuesday
  603. break;
  604. case '%L': $var = date('L', $time);
  605. break;
  606. case '%m': $var = date('m', $time);
  607. break;
  608. case '%M': $var = ($translate === FALSE) ? date('M', $time) : $LANG->line(date('M', $time)); // Jan, Feb
  609. break;
  610. case '%n': $var = date('n', $time);
  611. break;
  612. case '%O': $var = ($localized_tz === TRUE) ? date('O', $time) : gmdate('O', $time);
  613. break;
  614. case '%r': $var = ($translate === FALSE) ? date('D', $time).date(', d ', $time).date('M', $time).date(' Y H:i:s O', $time) : $LANG->line(date('D', $time)).date(', d ', $time).$LANG->line(date('M', $time)).date(' Y H:i:s O', $time);
  615. break;
  616. case '%s': $var = date('s', $time);
  617. break;
  618. case '%S': $var = date('S', $time);
  619. break;
  620. case '%t': $var = date('t', $time);
  621. break;
  622. case '%T': $var = ($localized_tz === TRUE) ? $this->ctz : gmdate('T', $time);
  623. break;
  624. case '%U': $var = date('U', $time);
  625. break;
  626. case '%w': $var = date('w', $time);
  627. break;
  628. case '%W': $var = date('W', $time);
  629. break;
  630. case '%y': $var = date('y', $time);
  631. break;
  632. case '%Y': $var = date('Y', $time);
  633. break;
  634. case '%Q': $var = ($localized_tz === TRUE) ? $this->zone_offset($SESS->userdata['timezone']) : '+00:00';
  635. break;
  636. case '%z': $var = date('z', $time);
  637. break;
  638. case '%Z': $var = ($localized_tz === TRUE) ? date('Z', $time) : gmdate('Z', $time);
  639. break;
  640. default : $var = '';
  641. break;
  642. }
  643. $this->cached[$time][$which] = $var;
  644. return $var;
  645. }
  646. /* END */
  647. /** ----------------------------------------------
  648. /** GMT Offset - Ouputs: +01:00
  649. /** ----------------------------------------------*/
  650. function zone_offset($tz = '')
  651. {
  652. if ($tz == '')
  653. {
  654. return '+00:00';
  655. }
  656. $zone = trim($this->zones[$tz]);
  657. if ( ! strstr($zone, '.'))
  658. {
  659. $zone .= ':00';
  660. }
  661. $zone = str_replace(".5", ':30', $zone);
  662. if (substr($zone, 0, 1) != '-')
  663. {
  664. $zone = '+'.$zone;
  665. }
  666. $zone = preg_replace("/^(.{1})([0-9]{1}):(\d+)$/", "\\1D\\2:\\3", $zone);
  667. $zone = str_replace("D", '0', $zone);
  668. return $zone;
  669. }
  670. /* END */
  671. /** ----------------------------------------------
  672. /** Create timezone localization pull-down menu
  673. /** ----------------------------------------------*/
  674. function timezone_menu($default = '')
  675. {
  676. global $LANG, $DSP;
  677. $r = "<div class='default'>";
  678. $r .= "<select name='server_timezone' class='select'>";
  679. foreach ($this->zones as $key => $val)
  680. {
  681. $selected = ($default == $key) ? " selected='selected'" : '';
  682. $r .= "<option value='{$key}'{$selected}>".$LANG->line($key)."</option>\n";
  683. }
  684. $r .= "</select>";
  685. $r .= "</div>";
  686. return $r;
  687. }
  688. /* END */
  689. /** -------------------------------------
  690. /** Timezones
  691. /** -------------------------------------*/
  692. // This array is used to render the localization pull-down menu
  693. function zones()
  694. {
  695. // Note: Don't change the order of these even though
  696. // some items appear to be in the wrong order
  697. return array(
  698. 'UM12' => -12,
  699. 'UM11' => -11,
  700. 'UM10' => -10,
  701. 'UM95' => -9.5,
  702. 'UM9' => -9,
  703. 'UM8' => -8,
  704. 'UM7' => -7,
  705. 'UM6' => -6,
  706. 'UM5' => -5,
  707. 'UM45' => -4.5,
  708. 'UM4' => -4,
  709. 'UM35' => -3.5,
  710. 'UM3' => -3,
  711. 'UM2' => -2,
  712. 'UM1' => -1,
  713. 'UTC' => 0,
  714. 'UP1' => +1,
  715. 'UP2' => +2,
  716. 'UP3' => +3,
  717. 'UP35' => +3.5,
  718. 'UP4' => +4,
  719. 'UP45' => +4.5,
  720. 'UP5' => +5,
  721. 'UP55' => +5.5,
  722. 'UP575' => +5.75,
  723. 'UP6' => +6,
  724. 'UP65' => +6.5,
  725. 'UP7' => +7,
  726. 'UP8' => +8,
  727. 'UP875' => +8.75,
  728. 'UP9' => +9,
  729. 'UP95' => +9.5,
  730. 'UP10' => +10,
  731. 'UP105' => +10.5,
  732. 'UP11' => +11,
  733. 'UP115' => +11.5,
  734. 'UP12' => +12,
  735. 'UP1275' => +12.75,
  736. 'UP13' => +13,
  737. 'UP14' => +14
  738. );
  739. }
  740. /* END */
  741. /** --------------------------------------------
  742. /** Set localized timezone
  743. /** --------------------------------------------*/
  744. function set_localized_timezone()
  745. {
  746. global $PREFS, $SESS;
  747. $zones = array(
  748. 'UM12' => array('', ''),
  749. 'UM11' => array('SST', 'SST'),
  750. 'UM10' => array('HST', 'HST'),
  751. 'UM95' => array('MART','MART'),
  752. 'UM9' => array('AKST','AKDT'),
  753. 'UM8' => array('PST', 'PDT'),
  754. 'UM7' => array('MST', 'MDT'),
  755. 'UM6' => array('CST', 'CDT'),
  756. 'UM5' => array('EST', 'EDT'),
  757. 'UM45' => array('VET', 'VET'),
  758. 'UM4' => array('AST', 'ADT'),
  759. 'UM35' => array('NST', 'NDT'),
  760. 'UM3' => array('ADT', 'ADT'),
  761. 'UM2' => array('MAST','MAST'),
  762. 'UM1' => array('AZOT','AZOT'),
  763. 'UTC' => array('GMT', 'GMT'),
  764. 'UP1' => array('MET', 'MET'),
  765. 'UP2' => array('EET', 'EET'),
  766. 'UP3' => array('BT', 'BT'),
  767. 'UP35' => array('IRT', 'IRT'),
  768. 'UP4' => array('ZP4', 'ZP4'),
  769. 'UP45' => array('AFT', 'AFT'),
  770. 'UP5' => array('ZP5', 'ZP5'),
  771. 'UP55' => array('IST', 'IDT'),
  772. 'UP575' => array('NPT', 'NPT'),
  773. 'UP6' => array('ZP6', 'ZP6'),
  774. 'UP65' => array('BURT','BURT'),
  775. 'UP7' => array('WAST','WADT'),
  776. 'UP8' => array('WST','WDT'),
  777. 'UP875' => array('CWST','CWDT'),
  778. 'UP9' => array('JST', 'JDT'),
  779. 'UP95' => array('CST', 'CDT'),
  780. 'UP10' => array('AEST','AEDT'),
  781. 'UP105' => array('LHST','LHST'),
  782. 'UP11' => array('MAGT','MAGT'),
  783. 'UP115' => array('NFT', 'NFT'),
  784. 'UP12' => array('NZST','NZDT'),
  785. 'UP1275'=> array('CHAST','CHAST'),
  786. 'UP13' => array('PHOT','PHOT'),
  787. 'UP14' => array('LINT','LINT')
  788. );
  789. if ($SESS->userdata['timezone'] == '')
  790. {
  791. $zone = $PREFS->ini('server_timezone');
  792. $dst = ($PREFS->ini('daylight_savings') == 'y') ? TRUE : FALSE;
  793. }
  794. else
  795. {
  796. $zone = $SESS->userdata['timezone'];
  797. $dst = ($SESS->userdata['daylight_savings'] == 'y') ? TRUE : FALSE;
  798. }
  799. if (isset($zones[$zone]))
  800. {
  801. if ($dst == FALSE)
  802. {
  803. return $zones[$zone]['0'];
  804. }
  805. else
  806. {
  807. return $zones[$zone]['1'];
  808. }
  809. }
  810. return 'GMT';
  811. }
  812. /* END */
  813. /** ----------------------------------------
  814. /** Fetch Days in Month
  815. /** ----------------------------------------*/
  816. // Returns the number of days for the given month/year
  817. // Takes leap years into consideration
  818. function fetch_days_in_month($month, $year)
  819. {
  820. $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  821. if ($month < 1 || $month > 12)
  822. {
  823. return 0;
  824. }
  825. if ($month == 2)
  826. {
  827. if ($year % 400 == 0 || ($year % 4 == 0 AND $year % 100 != 0))
  828. {
  829. return 29;
  830. }
  831. }
  832. return $days_in_month[$month - 1];
  833. }
  834. /* END */
  835. /** ----------------------------------------
  836. /** Adjust Date
  837. /** ----------------------------------------*/
  838. // This function is used by the calendar. It verifies that
  839. // the month/day are within the correct range and adjusts
  840. // if necessary. For example: Day 34 in Feburary would
  841. // be adjusted to March 6th.
  842. function adjust_date($month, $year, $pad = FALSE)
  843. {
  844. $date = array();
  845. $date['month'] = $month;
  846. $date['year'] = $year;
  847. while ($date['month'] > 12)
  848. {
  849. $date['month'] -= 12;
  850. $date['year']++;
  851. }
  852. while ($date['month'] <= 0)
  853. {
  854. $date['month'] += 12;
  855. $date['year']--;
  856. }
  857. if ($pad == TRUE AND strlen($date['month']) == 1)
  858. {
  859. $date['month'] = '0'.$date['month'];
  860. }
  861. return $date;
  862. }
  863. /* END */
  864. }
  865. // END CLASS
  866. ?>