3 /* Reminder: always indent with 4 spaces (no tabs). */
4 // +---------------------------------------------------------------------------+
6 // +---------------------------------------------------------------------------+
7 // | timezoneconfig.class.php |
9 // | Helper class for time zone handling |
10 // +---------------------------------------------------------------------------+
11 // | Copyright (C) 2009 by the following authors: |
13 // | Authors: Dirk Haun - dirk AT haun-online DOT de |
14 // | based on earlier work by Oliver Spiesshofer, Yew Loong, and others |
15 // +---------------------------------------------------------------------------+
17 // | This program is free software; you can redistribute it and/or |
18 // | modify it under the terms of the GNU General Public License |
19 // | as published by the Free Software Foundation; either version 2 |
20 // | of the License, or (at your option) any later version. |
22 // | This program is distributed in the hope that it will be useful, |
23 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
24 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
25 // | GNU General Public License for more details. |
27 // | You should have received a copy of the GNU General Public License |
28 // | along with this program; if not, write to the Free Software Foundation, |
29 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
31 // +---------------------------------------------------------------------------+
34 * Geeklog Time Zone Config class
36 * A collection of static (for now) methods dealing with time zone handling.
38 * For the original "Timezone Hack" discussion, see
39 * @link http://www.geeklog.net/forum/viewtopic.php?showtopic=21232
41 * @author Dirk Haun, dirk AT haun-online DOT de
44 class TimeZoneConfig {
47 * Set the system's timezone
49 * @param string $tz timezone to set; use $_CONF['timezone'] if empty
54 function setSystemTimeZone($tz = '')
58 static $system_timezone = '';
60 if (empty($tz) && !empty($_CONF['timezone'])) {
61 $tz = $_CONF['timezone'];
65 if ($tz != $system_timezone) {
66 if (function_exists('date_default_timezone_set')) {
67 if (! @date_default_timezone_set($tz)) {
68 date_default_timezone_set('UTC');
69 COM_errorLog("Timezone '$tz' not valid - using 'UTC' instead", 1);
70 $system_timezone = 'UTC';
72 $system_timezone = $tz;
74 } elseif (!ini_get('safe_mode') && function_exists('putenv')) {
75 // aka "Timezone Hack"
77 $system_timezone = $tz;
80 } elseif (function_exists('date_default_timezone_get')) {
81 // this is not ideal but will stop PHP 5.3.0ff from complaining ...
82 $system_timezone = @date_default_timezone_get();
83 date_default_timezone_set($system_timezone);
88 * Set the user's preferred timezone
90 * Note that does nothing if $_CONF['timezone'] is empty, i.e. if no
91 * system timezone is defined, we don't set a user timezone either.
97 function setUserTimeZone()
101 if (! empty($_CONF['timezone'])) {
102 $tz = TimeZoneConfig::getUserTimeZone();
104 TimeZoneConfig::setSystemTimeZone($tz);
110 * Get the user's preferred timezone
112 * @return string name of the timezone
116 function getUserTimeZone()
118 global $_CONF, $_USER;
120 // handle like the theme cookie, i.e. use if user is not logged in
121 if (isset($_COOKIE[$_CONF['cookie_tzid']]) && empty($_USER['tzid'])) {
122 $_USER['tzid'] = $_COOKIE[$_CONF['cookie_tzid']];
125 if (! empty($_USER['tzid'])) {
126 $timezone = $_USER['tzid'];
127 } elseif (! empty($_CONF['timezone'])) {
128 $timezone = $_CONF['timezone'];
129 } elseif (function_exists('date_default_timezone_get')) {
130 $timezone = @date_default_timezone_get();
132 require_once 'Date/TimeZone.php';
134 $tz_obj = Date_TimeZone::getDefault();
135 $timezone = $tz_obj->id;
142 * Provide a dropdown menu of the available timezones
144 * @return string HTML for the dropdown
148 function getTimeZoneDropDown($selected = '', $attributes = array())
150 $timezones = TimeZoneConfig::listAvailableTimeZones();
152 $selection = '<select';
153 foreach ($attributes as $name => $value) {
154 $selection .= sprintf(' %s="%s"', $name, $value);
156 $selection .= '>' . LB;
158 foreach ($timezones as $tzid => $tzdisplay) {
159 $selection .= '<option value="' . $tzid . '"';
160 if (!empty($selected) && ($selected == $tzid)) {
161 $selection .= ' selected="selected"';
163 $selection .= ">$tzdisplay</option>" . LB;
165 $selection .= '</select>';
171 * Provide a list of available timezones
173 * @return array array of (timezone-short-name, timezone-long-name) pairs
177 function listAvailableTimeZones()
179 $timezones = array();
181 // use only timezones that contain one of these
182 $useonly = array('Africa', 'America', 'Antarctica', 'Arctic', 'Asia',
183 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific',
186 // check if we can use the DateTimeZone class
187 $useDateTimeZone = false;
188 if (class_exists('DateTimeZone') && class_exists('ReflectionClass')) {
189 $rc = new ReflectionClass('DateTimeZone');
190 if ($rc->hasMethod('listAbbreviations')) {
191 $useDateTimeZone = true;
195 if ($useDateTimeZone) {
197 $T = DateTimeZone::listAbbreviations();
198 foreach ($T as $tzid => $entries) {
199 $shortname = strtoupper($tzid);
200 foreach ($entries as $data) {
201 $tzcheck = explode('/', $data['timezone_id']);
202 if (! in_array($tzcheck[0], $useonly)) {
206 $hours = $data['offset'] / 3600;
207 $hours = ((int) ($hours * 100) / 100);
212 $tzcode = str_replace('_', ' ', $data['timezone_id']);
213 $tzcode = htmlspecialchars($tzcode);
214 $formattedTimezone = "$hours, $shortname ($tzcode)";
215 $timezones[$data['timezone_id']] = $formattedTimezone;
219 } else { // DateTimeZone not available - use PEAR Date class
221 require_once 'Date/TimeZone.php';
223 $T = $GLOBALS['_DATE_TIMEZONE_DATA'];
225 foreach ($T as $tzid => $tDetails) {
226 $tzcheck = explode('/', $tzid);
227 if (! in_array($tzcheck[0], $useonly)) {
230 if (!empty($tzcheck[1]) &&
231 (strpos($tzcheck[1], 'Riyadh') === 0)) {
232 // these time zones are based on solar time and not widely
237 $tzcode = str_replace('_', ' ', $tzid);
238 $tzcode = htmlspecialchars($tzcode);
239 $hours = $tDetails['offset'] / (3600 * 1000);
240 $hours = ((int) ($hours * 100) / 100);
245 $formattedTimezone = "$hours, {$tDetails['shortname']} ($tzcode)";
246 $timezones[$tzid] = $formattedTimezone;
251 uasort($timezones, array('TimeZoneConfig', '_sort_by_timezone'));
257 * Helper method: Sort timezone entries
259 * @param string $tz1 first timezone
260 * @param string $tz2 second timezone
261 * @return int 0: equal, <0: first<second, >0: first>second
266 function _sort_by_timezone($tz1, $tz2)
268 $p1 = explode(',', $tz1);
269 $p2 = explode(',', $tz2);
275 return ($o1 < $o2 ? -1 : 1);
278 // drop offset, pop timezone name, then add it to the end again
280 $tz1 = trim(implode(',', $p1));
281 $p1 = explode(' ', $tz1);
282 $x1 = array_shift($p1);
284 $tz1 = implode(' ', $p1);
287 $tz2 = trim(implode(',', $p2));
288 $p2 = explode(' ', $tz2);
289 $x2 = array_shift($p2);
291 $tz2 = implode(' ', $p2);
293 return strcmp($tz1, $tz2);