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 * Get the user's preferred timezone
90 * @return string name of the timezone
94 function getUserTimeZone()
96 global $_CONF, $_USER;
98 // handle like the theme cookie, i.e. use if user is not logged in
99 if (isset($_COOKIE[$_CONF['cookie_tzid']]) && empty($_USER['tzid'])) {
100 $_USER['tzid'] = $_COOKIE[$_CONF['cookie_tzid']];
103 if (! empty($_USER['tzid'])) {
104 $timezone = $_USER['tzid'];
105 } elseif (! empty($_CONF['timezone'])) {
106 $timezone = $_CONF['timezone'];
107 } elseif (function_exists('date_default_timezone_get')) {
108 $timezone = @date_default_timezone_get();
110 require_once 'Date/TimeZone.php';
112 $tz_obj = Date_TimeZone::getDefault();
113 $timezone = $tz_obj->id;
120 * Provide a dropdown menu of the available timezones
122 * @return string HTML for the dropdown
126 function getTimeZoneDropDown($selected = '', $attributes = array())
128 $timezones = TimeZoneConfig::listAvailableTimeZones();
130 $selection = '<select';
131 foreach ($attributes as $name => $value) {
132 $selection .= sprintf(' %s="%s"', $name, $value);
134 $selection .= '>' . LB;
136 foreach ($timezones as $tzid => $tzdisplay) {
137 $selection .= '<option value="' . $tzid . '"';
138 if (!empty($selected) && ($selected == $tzid)) {
139 $selection .= ' selected="selected"';
141 $selection .= ">$tzdisplay</option>" . LB;
143 $selection .= '</select>';
149 * Provide a list of available timezones
151 * @return array array of (timezone-short-name, timezone-long-name) pairs
155 function listAvailableTimeZones()
157 $timezones = array();
159 // use only timezones that contain one of these
160 $useonly = array('Africa', 'America', 'Antarctica', 'Arctic', 'Asia',
161 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific',
164 // check if we can use the DateTimeZone class
165 $useDateTimeZone = false;
166 if (class_exists('DateTimeZone') && class_exists('ReflectionClass')) {
167 $rc = new ReflectionClass('DateTimeZone');
168 if ($rc->hasMethod('listAbbreviations')) {
169 $useDateTimeZone = true;
173 if ($useDateTimeZone) {
175 $T = DateTimeZone::listAbbreviations();
176 foreach ($T as $tzid => $entries) {
177 $shortname = strtoupper($tzid);
178 foreach ($entries as $data) {
179 $tzcheck = explode('/', $data['timezone_id']);
180 if (! in_array($tzcheck[0], $useonly)) {
184 $hours = $data['offset'] / 3600;
185 $hours = ((int) ($hours * 100) / 100);
190 $tzcode = str_replace('_', ' ', $data['timezone_id']);
191 $tzcode = htmlspecialchars($tzcode);
192 $formattedTimezone = "$hours, $shortname ($tzcode)";
193 $timezones[$data['timezone_id']] = $formattedTimezone;
197 } else { // DateTimeZone not available - use PEAR Date class
199 require_once 'Date/TimeZone.php';
201 $T = $GLOBALS['_DATE_TIMEZONE_DATA'];
203 foreach ($T as $tzid => $tDetails) {
204 $tzcheck = explode('/', $tzid);
205 if (! in_array($tzcheck[0], $useonly)) {
208 if (!empty($tzcheck[1]) &&
209 (strpos($tzcheck[1], 'Riyadh') === 0)) {
210 // these time zones are based on solar time and not widely
215 $tzcode = str_replace('_', ' ', $tzid);
216 $tzcode = htmlspecialchars($tzcode);
217 $hours = $tDetails['offset'] / (3600 * 1000);
218 $hours = ((int) ($hours * 100) / 100);
223 $formattedTimezone = "$hours, {$tDetails['shortname']} ($tzcode)";
224 $timezones[$tzid] = $formattedTimezone;
229 uasort($timezones, array('TimeZoneConfig', '_sort_by_timezone'));
235 * Helper method: Sort timezone entries
237 * @param string $tz1 first timezone
238 * @param string $tz2 second timezone
239 * @return int 0: equal, <0: first<second, >0: first>second
244 function _sort_by_timezone($tz1, $tz2)
246 $p1 = explode(',', $tz1);
247 $p2 = explode(',', $tz2);
253 return ($o1 < $o2 ? -1 : 1);
256 // drop offset, pop timezone name, then add it to the end again
258 $tz1 = trim(implode(',', $p1));
259 $p1 = explode(' ', $tz1);
260 $x1 = array_shift($p1);
262 $tz1 = implode(' ', $p1);
265 $tz2 = trim(implode(',', $p2));
266 $p2 = explode(' ', $tz2);
267 $x2 = array_shift($p2);
269 $tz2 = implode(' ', $p2);
271 return strcmp($tz1, $tz2);