Check timezone cookie and date_default_timezone_get for the user's preferred time zone
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 if (empty($tz) && !empty($_CONF['timezone'])) {
59 $tz = $_CONF['timezone'];
63 if (function_exists('date_default_timezone_set')) {
64 if (! @date_default_timezone_set($tz)) {
65 date_default_timezone_set('UTC');
66 COM_errorLog("Timezone '$tz' not valid - using 'UTC' instead", 1);
68 } elseif (!ini_get('safe_mode') && function_exists('putenv')) {
69 // aka "Timezone Hack"
72 } elseif (function_exists('date_default_timezone_get')) {
73 // this is not ideal but will stop PHP 5.3.0ff from complaining ...
74 date_default_timezone_set(@date_default_timezone_get());
79 * Get the user's preferred timezone
81 * @return string name of the timezone
85 function getUserTimeZone()
87 global $_CONF, $_USER;
89 // handle like the theme cookie, i.e. use if user is not logged in
90 if (isset($_COOKIE[$_CONF['cookie_tzid']]) && empty($_USER['tzid'])) {
91 $_USER['tzid'] = $_COOKIE[$_CONF['cookie_tzid']];
94 if (! empty($_USER['tzid'])) {
95 $timezone = $_USER['tzid'];
96 } elseif (! empty($_CONF['timezone'])) {
97 $timezone = $_CONF['timezone'];
98 } elseif (function_exists('date_default_timezone_get')) {
99 $timezone = @date_default_timezone_get();
101 require_once 'Date/TimeZone.php';
103 $tz_obj = Date_TimeZone::getDefault();
104 $timezone = $tz_obj->id;
111 * Provide a dropdown menu of the available timezones
113 * @return string HTML for the dropdown
117 function getTimeZoneDropDown($selected = '', $attributes = array())
119 $timezones = TimeZoneConfig::listAvailableTimeZones();
121 $selection = '<select';
122 foreach ($attributes as $name => $value) {
123 $selection .= sprintf(' %s="%s"', $name, $value);
125 $selection .= '>' . LB;
127 foreach ($timezones as $tzid => $tzdisplay) {
128 $selection .= '<option value="' . $tzid . '"';
129 if (!empty($selected) && ($selected == $tzid)) {
130 $selection .= ' selected="selected"';
132 $selection .= ">$tzdisplay</option>" . LB;
134 $selection .= '</select>';
140 * Provide a list of available timezones
142 * @return array array of (timezone-short-name, timezone-long-name) pairs
146 function listAvailableTimeZones()
148 $timezones = array();
150 // use only timezones that contain one of these
151 $useonly = array('Africa', 'America', 'Antarctica', 'Arctic', 'Asia',
152 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific',
155 // check if we can use the DateTimeZone class
156 $useDateTimeZone = false;
157 if (class_exists('DateTimeZone') && class_exists('ReflectionClass')) {
158 $rc = new ReflectionClass('DateTimeZone');
159 if ($rc->hasMethod('listAbbreviations')) {
160 $useDateTimeZone = true;
164 if ($useDateTimeZone) {
166 $T = DateTimeZone::listAbbreviations();
167 foreach ($T as $tzid => $entries) {
168 $shortname = strtoupper($tzid);
169 foreach ($entries as $data) {
170 $tzcheck = explode('/', $data['timezone_id']);
171 if (! in_array($tzcheck[0], $useonly)) {
175 $hours = $data['offset'] / 3600;
176 $hours = ((int) ($hours * 100) / 100);
181 $tzcode = str_replace('_', ' ', $data['timezone_id']);
182 $tzcode = htmlspecialchars($tzcode);
183 $formattedTimezone = "$hours, $shortname ($tzcode)";
184 $timezones[$data['timezone_id']] = $formattedTimezone;
188 } else { // DateTimeZone not available - use PEAR Date class
190 require_once 'Date/TimeZone.php';
192 $T = $GLOBALS['_DATE_TIMEZONE_DATA'];
194 foreach ($T as $tzid => $tDetails) {
195 $tzcheck = explode('/', $tzid);
196 if (! in_array($tzcheck[0], $useonly)) {
199 if (!empty($tzcheck[1]) &&
200 (strpos($tzcheck[1], 'Riyadh') === 0)) {
201 // these time zones are based on solar time and not widely
206 $tzcode = str_replace('_', ' ', $tzid);
207 $tzcode = htmlspecialchars($tzcode);
208 $hours = $tDetails['offset'] / (3600 * 1000);
209 $hours = ((int) ($hours * 100) / 100);
214 $formattedTimezone = "$hours, {$tDetails['shortname']} ($tzcode)";
215 $timezones[$tzid] = $formattedTimezone;
220 uasort($timezones, array('TimeZoneConfig', '_sort_by_timezone'));
226 * Helper method: Sort timezone entries
228 * @param string $tz1 first timezone
229 * @param string $tz2 second timezone
230 * @return int 0: equal, <0: first<second, >0: first>second
235 function _sort_by_timezone($tz1, $tz2)
237 $p1 = explode(',', $tz1);
238 $p2 = explode(',', $tz2);
244 return ($o1 < $o2 ? -1 : 1);
247 // drop offset, pop timezone name, then add it to the end again
249 $tz1 = trim(implode(',', $p1));
250 $p1 = explode(' ', $tz1);
251 $x1 = array_shift($p1);
253 $tz1 = implode(' ', $p1);
256 $tz2 = trim(implode(',', $p2));
257 $p2 = explode(' ', $tz2);
258 $x2 = array_shift($p2);
260 $tz2 = implode(' ', $p2);
262 return strcmp($tz1, $tz2);