1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/system/classes/timezoneconfig.class.php Sun Sep 20 11:00:03 2009 +0200
1.3 @@ -0,0 +1,260 @@
1.4 +<?php
1.5 +
1.6 +/* Reminder: always indent with 4 spaces (no tabs). */
1.7 +// +---------------------------------------------------------------------------+
1.8 +// | Geeklog 1.6 |
1.9 +// +---------------------------------------------------------------------------+
1.10 +// | timezoneconfig.class.php |
1.11 +// | |
1.12 +// | Helper class for time zone handling |
1.13 +// +---------------------------------------------------------------------------+
1.14 +// | Copyright (C) 2009 by the following authors: |
1.15 +// | |
1.16 +// | Authors: Dirk Haun - dirk AT haun-online DOT de |
1.17 +// | based on earlier work by Oliver Spiesshofer, Yew Loong, and others |
1.18 +// +---------------------------------------------------------------------------+
1.19 +// | |
1.20 +// | This program is free software; you can redistribute it and/or |
1.21 +// | modify it under the terms of the GNU General Public License |
1.22 +// | as published by the Free Software Foundation; either version 2 |
1.23 +// | of the License, or (at your option) any later version. |
1.24 +// | |
1.25 +// | This program is distributed in the hope that it will be useful, |
1.26 +// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
1.27 +// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1.28 +// | GNU General Public License for more details. |
1.29 +// | |
1.30 +// | You should have received a copy of the GNU General Public License |
1.31 +// | along with this program; if not, write to the Free Software Foundation, |
1.32 +// | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
1.33 +// | |
1.34 +// +---------------------------------------------------------------------------+
1.35 +
1.36 +/**
1.37 +* Geeklog Time Zone Config class
1.38 +*
1.39 +* A collection of static (for now) methods dealing with time zone handling.
1.40 +*
1.41 +* For the original "Timezone Hack" discussion, see
1.42 +* @link http://www.geeklog.net/forum/viewtopic.php?showtopic=21232
1.43 +*
1.44 +* @author Dirk Haun, dirk AT haun-online DOT de
1.45 +*
1.46 +*/
1.47 +class TimeZoneConfig {
1.48 +
1.49 + /**
1.50 + * Set the system's timezone
1.51 + *
1.52 + * @param string $tz timezone to set; use $_CONF['timezone'] if empty
1.53 + * @return void
1.54 + * @static
1.55 + *
1.56 + */
1.57 + function setSystemTimeZone($tz = '')
1.58 + {
1.59 + global $_CONF;
1.60 +
1.61 + if (empty($tz) && !empty($_CONF['timezone'])) {
1.62 + $tz = $_CONF['timezone'];
1.63 + }
1.64 +
1.65 + if (! empty($tz)) {
1.66 + if (function_exists('date_default_timezone_set')) {
1.67 + if (! @date_default_timezone_set($tz)) {
1.68 + date_default_timezone_set('UTC');
1.69 + COM_errorLog("Timezone '$tz' not valid - using 'UTC' instead", 1);
1.70 + }
1.71 + } elseif (!ini_get('safe_mode') && function_exists('putenv')) {
1.72 + // aka "Timezone Hack"
1.73 + putenv('TZ=' . $tz);
1.74 + }
1.75 + } elseif (function_exists('date_default_timezone_get')) {
1.76 + // this is not ideal but will stop PHP 5.3.0ff from complaining ...
1.77 + date_default_timezone_set(@date_default_timezone_get());
1.78 + }
1.79 + }
1.80 +
1.81 + /**
1.82 + * Get the user's preferred timezone
1.83 + *
1.84 + * @return string name of the timezone
1.85 + * @static
1.86 + *
1.87 + */
1.88 + function getUserTimeZone()
1.89 + {
1.90 + global $_CONF, $_USER;
1.91 +
1.92 + if (! empty($_USER['tzid'])) {
1.93 + $timezone = $_USER['tzid'];
1.94 + } elseif (! empty($_CONF['timezone'])) {
1.95 + $timezone = $_CONF['timezone'];
1.96 + } else {
1.97 + require_once 'Date/TimeZone.php';
1.98 +
1.99 + $tz_obj = Date_TimeZone::getDefault();
1.100 + $timezone = $tz_obj->id;
1.101 + }
1.102 +
1.103 + return $timezone;
1.104 + }
1.105 +
1.106 + /**
1.107 + * Provide a dropdown menu of the available timezones
1.108 + *
1.109 + * @return string HTML for the dropdown
1.110 + * @static
1.111 + *
1.112 + */
1.113 + function getTimeZoneDropDown($selected = '', $attributes = array())
1.114 + {
1.115 + $timezones = TimeZoneConfig::listAvailableTimeZones();
1.116 +
1.117 + $selection = '<select';
1.118 + foreach ($attributes as $name => $value) {
1.119 + $selection .= sprintf(' %s="%s"', $name, $value);
1.120 + }
1.121 + $selection .= '>' . LB;
1.122 +
1.123 + foreach ($timezones as $tzid => $tzdisplay) {
1.124 + $selection .= '<option value="' . $tzid . '"';
1.125 + if (!empty($selected) && ($selected == $tzid)) {
1.126 + $selection .= ' selected="selected"';
1.127 + }
1.128 + $selection .= ">$tzdisplay</option>" . LB;
1.129 + }
1.130 + $selection .= '</select>';
1.131 +
1.132 + return $selection;
1.133 + }
1.134 +
1.135 + /**
1.136 + * Provide a list of available timezones
1.137 + *
1.138 + * @return array array of (timezone-short-name, timezone-long-name) pairs
1.139 + * @static
1.140 + *
1.141 + */
1.142 + function listAvailableTimeZones()
1.143 + {
1.144 + $timezones = array();
1.145 +
1.146 + // use only timezones that contain one of these
1.147 + $useonly = array('Africa', 'America', 'Antarctica', 'Arctic', 'Asia',
1.148 + 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific',
1.149 + 'UTC');
1.150 +
1.151 + // check if we can use the DateTimeZone class
1.152 + $useDateTimeZone = false;
1.153 + if (class_exists('DateTimeZone') && class_exists('ReflectionClass')) {
1.154 + $rc = new ReflectionClass('DateTimeZone');
1.155 + if ($rc->hasMethod('listAbbreviations')) {
1.156 + $useDateTimeZone = true;
1.157 + }
1.158 + }
1.159 +
1.160 + if ($useDateTimeZone) {
1.161 +
1.162 + $T = DateTimeZone::listAbbreviations();
1.163 + foreach ($T as $tzid => $entries) {
1.164 + $shortname = strtoupper($tzid);
1.165 + foreach ($entries as $data) {
1.166 + $tzcheck = explode('/', $data['timezone_id']);
1.167 + if (! in_array($tzcheck[0], $useonly)) {
1.168 + continue;
1.169 + }
1.170 +
1.171 + $hours = $data['offset'] / 3600;
1.172 + $hours = ((int) ($hours * 100) / 100);
1.173 + if ($hours > 0) {
1.174 + $hours = "+$hours";
1.175 + }
1.176 +
1.177 + $tzcode = str_replace('_', ' ', $data['timezone_id']);
1.178 + $tzcode = htmlspecialchars($tzcode);
1.179 + $formattedTimezone = "$hours, $shortname ($tzcode)";
1.180 + $timezones[$data['timezone_id']] = $formattedTimezone;
1.181 + }
1.182 + }
1.183 +
1.184 + } else { // DateTimeZone not available - use PEAR Date class
1.185 +
1.186 + require_once 'Date/TimeZone.php';
1.187 +
1.188 + $T = $GLOBALS['_DATE_TIMEZONE_DATA'];
1.189 +
1.190 + foreach ($T as $tzid => $tDetails) {
1.191 + $tzcheck = explode('/', $tzid);
1.192 + if (! in_array($tzcheck[0], $useonly)) {
1.193 + continue;
1.194 + }
1.195 + if (!empty($tzcheck[1]) &&
1.196 + (strpos($tzcheck[1], 'Riyadh') === 0)) {
1.197 + // these time zones are based on solar time and not widely
1.198 + // supported - skip
1.199 + continue;
1.200 + }
1.201 +
1.202 + $tzcode = str_replace('_', ' ', $tzid);
1.203 + $tzcode = htmlspecialchars($tzcode);
1.204 + $hours = $tDetails['offset'] / (3600 * 1000);
1.205 + $hours = ((int) ($hours * 100) / 100);
1.206 + if ($hours > 0) {
1.207 + $hours = "+$hours";
1.208 + }
1.209 +
1.210 + $formattedTimezone = "$hours, {$tDetails['shortname']} ($tzcode)";
1.211 + $timezones[$tzid] = $formattedTimezone;
1.212 + }
1.213 +
1.214 + }
1.215 +
1.216 + uasort($timezones, 'TimeZoneConfig::_sort_by_timezone');
1.217 +
1.218 + return $timezones;
1.219 + }
1.220 +
1.221 + /**
1.222 + * Helper method: Sort timezone entries
1.223 + *
1.224 + * @param string $tz1 first timezone
1.225 + * @param string $tz2 second timezone
1.226 + * @return int 0: equal, <0: first<second, >0: first>second
1.227 + * @static
1.228 + * @access private
1.229 + *
1.230 + */
1.231 + function _sort_by_timezone($tz1, $tz2)
1.232 + {
1.233 + $p1 = explode(',', $tz1);
1.234 + $p2 = explode(',', $tz2);
1.235 +
1.236 + // compare offsets
1.237 + $o1 = $p1[0];
1.238 + $o2 = $p2[0];
1.239 + if ($o1 != $o2) {
1.240 + return ($o1 < $o2 ? -1 : 1);
1.241 + }
1.242 +
1.243 + // drop offset, pop timezone name, then add it to the end again
1.244 + array_shift($p1);
1.245 + $tz1 = trim(implode(',', $p1));
1.246 + $p1 = explode(' ', $tz1);
1.247 + $x1 = array_shift($p1);
1.248 + $p1[] = $x1;
1.249 + $tz1 = implode(' ', $p1);
1.250 +
1.251 + array_shift($p2);
1.252 + $tz2 = trim(implode(',', $p2));
1.253 + $p2 = explode(' ', $tz2);
1.254 + $x2 = array_shift($p2);
1.255 + $p2[] = $x2;
1.256 + $tz2 = implode(' ', $p2);
1.257 +
1.258 + return strcmp($tz1, $tz2);
1.259 + }
1.260 +
1.261 +}
1.262 +
1.263 +?>