PageRenderTime 70ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/html/AppCode/expressionengine/libraries/Localize.php

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