[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkLocalize/ -> AkTimeZone.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  /**
  12   * @package ActiveSupport
  13   * @subpackage I18n-L10n
  14   * @author Bermi Ferrer <bermi a.t akelos c.om>
  15   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  16   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  17   */
  18  
  19  
  20  
  21  
  22  /**
  23  * A value object representing a time zone. A time zone is simply a named
  24  * offset (in seconds) from GMT. Note that two time zone objects are only
  25  * equivalent if they have both the same offset, and the same name.
  26  * 
  27  * A TimeZone instance may be used to convert a Time value to the corresponding
  28  * time zone.
  29  * 
  30  * The class also includes a method named all(), which returns a list of all TimeZone objects.
  31  */
  32  class AkTimeZone
  33  {
  34      var $name;
  35      var $utc_offset;
  36      var $dst;
  37      var $zones = array();
  38      var $dst_zones = array();
  39  
  40      /**
  41      * Initiates a new AkTimeZone object with the given name and offset. The offset is
  42      * the number of seconds that this time zone is offset from UTC (GMT).
  43      */
  44      function init($name, $utc_offset, $dst = false)
  45      {
  46          $this->name = $name;
  47          $this->utc_offset = $utc_offset;
  48          $this->dst = $dst;
  49      }
  50  
  51      /**
  52      * Returns the offset of this time zone as a formatted string, of the
  53      * format "+HH:MM". If the offset is zero, this returns the empty
  54      * string. If $colon is false, a colon will not be inserted into the
  55      * result.
  56      */
  57      function getFormattedOffset($colon = true)
  58      {
  59          if($this->utc_offset == 0){
  60              return '';
  61          }
  62          $sign = ($this->utc_offset < 0 ? -1 : 1);
  63          $hours = abs($this->utc_offset) / 3600;
  64          $minutes = (abs($this->utc_offset) % 3600) / 60;
  65          return sprintf("%+03d%s%02d", $hours * $sign, $colon ? ":" : "", $minutes);
  66      }
  67  
  68      /**
  69      * Compute and return the current time, in the time zone represented by
  70      * AkTimeZone.
  71      */
  72      function now()
  73      {
  74          return $this->adjust(isset($this->_timestamp) ? $this->_timestamp : Ak::getTimestamp());
  75      }
  76  
  77      /**
  78      * Return the current date in this time zone.
  79      */
  80      function today()
  81      {
  82          return Ak::getDate($this->now(), Ak::locale('date_format'));
  83      }
  84  
  85      /**
  86      * Return the current time in this time zone.
  87      */
  88      function time()
  89      {
  90          return Ak::getDate($this->now(), Ak::locale('time_format'));
  91      }
  92  
  93      /**
  94      * Return the current time in this time zone.
  95      */
  96      function dateTime()
  97      {
  98          return Ak::getDate($this->now(), Ak::locale('date_time_format'));
  99      }
 100  
 101      /**
 102      * Adjust the given time to the time zone represented by AkTimeZone.
 103      */
 104      function adjust($time)
 105      {
 106          return $time + $this->utc_offset + ($this->dst && $this->inDst($time, $this->name) ? 3600 : 0) - AK_UTC_OFFSET;
 107      }
 108  
 109      /**
 110      * Reinterprets the given time value as a time in the current time
 111      * zone, and then adjusts it to return the corresponding time in the
 112      * local time zone.
 113      */
 114      function unadjust($time)
 115      {
 116          return $time - $this->utc_offset - ($this->dst && $this->inDst($time, $this->name) ? 3600 : 0) + AK_UTC_OFFSET;
 117      }
 118  
 119      /**
 120      * Compare this time zone to the parameter. The two are compared first on
 121      * their offsets, and then by name.
 122      */
 123      function compare($zone)
 124      {
 125          $result = $this->utc_offset > $zone->utc_offset ? 1 : ($zone->utc_offset > $this->utc_offset ? -1 : 0);
 126          $result = $result == 0 ? strcoll($this->name, $zone->name) : $result;
 127          return $result == 0 ? 0 : ($result > 0 ? 1 : -1);
 128      }
 129  
 130      /**
 131      * Returns a textual representation of this time zone.
 132      */
 133      function toString()
 134      {
 135          return '(GMT'.$this->getFormattedOffset().") $this->name";
 136      }
 137  
 138  
 139      function inDst($timestamp, $zone_name)
 140      {
 141          $env_tz = function_exists('date_default_timezone_get') ?  @date_default_timezone_get() : @getenv('TZ');
 142          function_exists('date_default_timezone_set') ?  date_default_timezone_set($zone_name) : @putenv('TZ='.$zone_name);
 143          $localtime = localtime($timestamp, true);
 144          if(!empty($env_tz)){
 145              function_exists('date_default_timezone_set') ?  date_default_timezone_set($env_tz) : @putenv('TZ='.$env_tz);
 146          }
 147          return !empty($localtime['tm_isdst']);
 148      }
 149  
 150  
 151      /**
 152      * Static method for creating new AkTimeZone object with the given name, offset and an options zones array.
 153      */
 154      function create($name, $timezone = null, $zones = null, $dst_zones = null)
 155      {
 156          $Zone = new AkTimeZone();
 157          if(!empty($zones)){
 158              $Zone->zones = $zones;
 159          }
 160          if(!empty($dst_zones)){
 161              $Zone->dst_zones = $dst_zones;
 162          }
 163          $details = $Zone->locateTimezone($name);
 164          $details = empty($details) ? $Zone->locateTimezone($timezone) : $details;
 165          if(!empty($details)){
 166              $name = $details['name'];
 167              $timezone =  $details['offset'];
 168          }
 169          $Zone->init($name, $timezone, !empty($Zone->dst_zones) && in_array($name, $Zone->dst_zones));
 170          unset($Zone->zones, $Zone->dst_zones);
 171          return $Zone;
 172      }
 173  
 174      /**
 175      * Locate a specific time zone. If the argument is a string, it
 176      * is interpreted to mean the name of the timezone to locate. If it is a
 177      * numeric value it is either the hour offset, or the second offset, of the
 178      * timezone to find. (The first one with that offset will be returned.)
 179      * Returns false if no such time zone is known to the system.
 180      */
 181      function locateTimezone($timezone_name_or_offset)
 182      {
 183          if(is_string($timezone_name_or_offset)){
 184              $timezones = $this->getTimezones();
 185              if(isset($timezones[$timezone_name_or_offset])){
 186                  return array('offset'=>$timezones[$timezone_name_or_offset], 'name' => $timezone_name_or_offset);
 187              }
 188          }elseif (is_numeric($timezone_name_or_offset)){
 189              $timezones = $this->getTimezones();
 190              foreach ($timezones as $zone => $offset){
 191                  if($timezone_name_or_offset == $offset){
 192                      return array('offset'=>$offset, 'name' => $zone);
 193                  }
 194              }
 195          }else{
 196              trigger_error(Ak::t('Invalid argument at AkTimeZone::locateTimezone(), you must supply a Time zone name or offset'), E_USER_NOTICE);
 197          }
 198          return false;
 199      }
 200  
 201      /**
 202      * Return an array of all time zones, as Place => Offset. There are multiple
 203      * places per time zone, in many cases, to make it easier for users to
 204      * find their own time zone.
 205      * 
 206      * Places prefixed with "-" are those who have DST in the South Hemisphere
 207      */
 208      function getTimezones()
 209      {
 210          if(empty($this->zones)){
 211              $zones =  Ak::t(
 212              '-43200 | Etc/GMT+12
 213  -39600 | Etc/GMT+11, MIT, Pacific/Apia, Pacific/Midway, Pacific/Niue, Pacific/Pago Pago, Pacific/Samoa, US/Samoa
 214  -36000 | -America/Adak, -America/Atka, Etc/GMT+10, HST, Pacific/Fakaofo, Pacific/Honolulu, Pacific/Johnston, Pacific/Rarotonga, Pacific/Tahiti, SystemV/HST10, -US/Aleutian, US/Hawaii
 215  -34200 | Pacific/Marquesas
 216  -32400 | -AST, -America/Anchorage, -America/Juneau, -America/Nome, -America/Yakutat, Etc/GMT+9, Pacific/Gambier, SystemV/YST9, -SystemV/YST9YDT, -US/Alaska
 217  -28800 | -America/Dawson, -America/Ensenada, -America/Los Angeles, -America/Tijuana, -America/Vancouver, -America/Whitehorse, -Canada/Pacific, -Canada/Yukon, Etc/GMT+8, -Mexico/BajaNorte, -PST, -PST8PDT, Pacific/Pitcairn, SystemV/PST8, -SystemV/PST8PDT, -US/Pacific, -US/Pacific-New
 218  -25200 | -America/Boise, -America/Cambridge Bay, -America/Chihuahua, America/Dawson Creek, -America/Denver, -America/Edmonton, America/Hermosillo, -America/Inuvik, -America/Mazatlan, America/Phoenix, -America/Shiprock, -America/Yellowknife, -Canada/Mountain, Etc/GMT+7, -MST, -MST7MDT, -Mexico/BajaSur, -Navajo, PNT, SystemV/MST7, -SystemV/MST7MDT, US/Arizona, -US/Mountain
 219  -21600 | America/Belize, -America/Cancun, -America/Chicago, America/Costa Rica, America/El Salvador, America/Guatemala, America/Managua, -America/Menominee, -America/Merida, America/Mexico City, -America/Monterrey, -America/North Dakota/Center, -America/Rainy River, -America/Rankin Inlet, America/Regina, America/Swift Current, America/Tegucigalpa, -America/Winnipeg, -CST, -CST6CDT, -Canada/Central, Canada/East-Saskatchewan, Canada/Saskatchewan, -Chile/EasterIsland, Etc/GMT+6, Mexico/General, -Pacific/Easter, Pacific/Galapagos, SystemV/CST6, -SystemV/CST6CDT, -US/Central
 220  -18000 | America/Bogota, America/Cayman, -America/Detroit, America/Eirunepe, America/Fort Wayne, -America/Grand Turk, America/Guayaquil, -America/Havana, America/Indiana/Indianapolis, America/Indiana/Knox, America/Indiana/Marengo, America/Indiana/Vevay, America/Indianapolis, -America/Iqaluit, America/Jamaica, -America/Kentucky/Louisville, -America/Kentucky/Monticello, America/Knox IN, America/Lima, -America/Louisville, -America/Montreal, -America/Nassau, -America/New York, -America/Nipigon, America/Panama, -America/Pangnirtung, America/Port-au-Prince, America/Porto Acre, America/Rio Branco, -America/Thunder Bay, Brazil/Acre, -Canada/Eastern, -Cuba, -EST, -EST5EDT, Etc/GMT+5, IET, Jamaica, SystemV/EST5, -SystemV/EST5EDT, US/East-Indiana, -US/Eastern, US/Indiana-Starke, -US/Michigan
 221  -14400 | America/Anguilla, America/Antigua, America/Aruba, -America/Asuncion, America/Barbados, America/Boa Vista, America/Caracas, -America/Cuiaba, America/Curacao, America/Dominica, -America/Glace Bay, -America/Goose Bay, America/Grenada, America/Guadeloupe, America/Guyana, -America/Halifax, America/La Paz, America/Manaus, America/Martinique, America/Montserrat, America/Port of Spain, America/Porto Velho, America/Puerto Rico, -America/Santiago, America/Santo Domingo, America/St Kitts, America/St Lucia, America/St Thomas, America/St Vincent, America/Thule, America/Tortola, America/Virgin, -Antarctica/Palmer, -Atlantic/Bermuda, -Atlantic/Stanley, Brazil/West, -Canada/Atlantic, -Chile/Continental, Etc/GMT+4, PRT, SystemV/AST4, -SystemV/AST4ADT
 222  -12600 | -America/St Johns, -CNT, -Canada/Newfoundland
 223  -10800 | AGT, -America/Araguaina, America/Belem, America/Buenos Aires, America/Catamarca, America/Cayenne, America/Cordoba, -America/Fortaleza, -America/Godthab, America/Jujuy, -America/Maceio, America/Mendoza, -America/Miquelon, America/Montevideo, America/Paramaribo, -America/Recife, America/Rosario, -America/Sao Paulo, -BET, -Brazil/East, Etc/GMT+3
 224   -7200 | America/Noronha, Atlantic/South Georgia, Brazil/DeNoronha, Etc/GMT+2
 225   -3600 | -America/Scoresbysund, -Atlantic/Azores, Atlantic/Cape Verde, Etc/GMT+1
 226       0 | Africa/Abidjan, Africa/Accra, Africa/Bamako, Africa/Banjul, Africa/Bissau, Africa/Casablanca, Africa/Conakry, Africa/Dakar, Africa/El Aaiun, Africa/Freetown, Africa/Lome, Africa/Monrovia, Africa/Nouakchott, Africa/Ouagadougou, Africa/Sao Tome, Africa/Timbuktu, America/Danmarkshavn, -Atlantic/Canary, -Atlantic/Faeroe, -Atlantic/Madeira, Atlantic/Reykjavik, Atlantic/St Helena, -Eire, Etc/GMT, Etc/GMT+0, Etc/GMT-0, Etc/GMT0, Etc/Greenwich, Etc/UCT, Etc/UTC, Etc/Universal, Etc/Zulu, -Europe/Belfast, -Europe/Dublin, -Europe/Lisbon, -Europe/London, -GB, -GB-Eire, GMT, GMT0, Greenwich, Iceland, -Portugal, UCT, UTC, Universal, -WET, Zulu
 227    3600 | Africa/Algiers, Africa/Bangui, Africa/Brazzaville, -Africa/Ceuta, Africa/Douala, Africa/Kinshasa, Africa/Lagos, Africa/Libreville, Africa/Luanda, Africa/Malabo, Africa/Ndjamena, Africa/Niamey, Africa/Porto-Novo, Africa/Tunis, -Africa/Windhoek, -Arctic/Longyearbyen, -Atlantic/Jan Mayen, -CET, -ECT, Etc/GMT-1, -Europe/Amsterdam, -Europe/Andorra, -Europe/Belgrade, -Europe/Berlin, -Europe/Bratislava, -Europe/Brussels, -Europe/Budapest, -Europe/Copenhagen, -Europe/Gibraltar, -Europe/Ljubljana, -Europe/Luxembourg, -Europe/Madrid, -Europe/Malta, -Europe/Monaco, -Europe/Oslo, -Europe/Paris, -Europe/Prague, -Europe/Rome, -Europe/San Marino, -Europe/Sarajevo, -Europe/Skopje, -Europe/Stockholm, -Europe/Tirane, -Europe/Vaduz, -Europe/Vatican, -Europe/Vienna, -Europe/Warsaw, -Europe/Zagreb, -Europe/Zurich, -MET, -Poland
 228    7200 | -ART, Africa/Blantyre, Africa/Bujumbura, -Africa/Cairo, Africa/Gaborone, Africa/Harare, Africa/Johannesburg, Africa/Kigali, Africa/Lubumbashi, Africa/Lusaka, Africa/Maputo, Africa/Maseru, Africa/Mbabane, Africa/Tripoli, -Asia/Amman, -Asia/Beirut, -Asia/Damascus, -Asia/Gaza, -Asia/Istanbul, -Asia/Jerusalem, -Asia/Nicosia, -Asia/Tel Aviv, CAT, -EET, -Egypt, Etc/GMT-2, -Europe/Athens, -Europe/Bucharest, -Europe/Chisinau, -Europe/Helsinki, -Europe/Istanbul, -Europe/Kaliningrad, -Europe/Kiev, -Europe/Minsk, -Europe/Nicosia, -Europe/Riga, -Europe/Simferopol, -Europe/Sofia, Europe/Tallinn, -Europe/Tiraspol, -Europe/Uzhgorod, Europe/Vilnius, -Europe/Zaporozhye, -Israel, Libya, -Turkey
 229   10800 | Africa/Addis Ababa, Africa/Asmera, Africa/Dar es Salaam, Africa/Djibouti, Africa/Kampala, Africa/Khartoum, Africa/Mogadishu, Africa/Nairobi, Antarctica/Syowa, Asia/Aden, -Asia/Baghdad, Asia/Bahrain, Asia/Kuwait, Asia/Qatar, Asia/Riyadh, EAT, Etc/GMT-3, -Europe/Moscow, Indian/Antananarivo, Indian/Comoro, Indian/Mayotte, -W-SU
 230   11224 | Asia/Riyadh87, Asia/Riyadh88, Asia/Riyadh89, Mideast/Riyadh87, Mideast/Riyadh88, Mideast/Riyadh89
 231   12600 | -Asia/Tehran, -Iran
 232   14400 | -Asia/Aqtau, -Asia/Baku, Asia/Dubai, Asia/Muscat, -Asia/Tbilisi, -Asia/Yerevan, Etc/GMT-4, -Europe/Samara, Indian/Mahe, Indian/Mauritius, Indian/Reunion, -NET
 233   16200 | Asia/Kabul
 234   18000 | -Asia/Aqtobe, Asia/Ashgabat, Asia/Ashkhabad, -Asia/Bishkek, Asia/Dushanbe, Asia/Karachi, Asia/Samarkand, Asia/Tashkent, -Asia/Yekaterinburg, Etc/GMT-5, Indian/Kerguelen, Indian/Maldives, PLT
 235   19800 | Asia/Calcutta, IST
 236   20700 | Asia/Katmandu
 237   21600 | Antarctica/Mawson, Antarctica/Vostok, -Asia/Almaty, Asia/Colombo, Asia/Dacca, Asia/Dhaka, -Asia/Novosibirsk, -Asia/Omsk, Asia/Thimbu, Asia/Thimphu, BST, Etc/GMT-6, Indian/Chagos
 238   23400 | Asia/Rangoon, Indian/Cocos
 239   25200 | Antarctica/Davis, Asia/Bangkok, Asia/Hovd, Asia/Jakarta, -Asia/Krasnoyarsk, Asia/Phnom Penh, Asia/Pontianak, Asia/Saigon, Asia/Vientiane, Etc/GMT-7, Indian/Christmas, VST
 240   28800 | Antarctica/Casey, Asia/Brunei, Asia/Chongqing, Asia/Chungking, Asia/Harbin, Asia/Hong Kong, -Asia/Irkutsk, Asia/Kashgar, Asia/Kuala Lumpur, Asia/Kuching, Asia/Macao, Asia/Manila, Asia/Shanghai, Asia/Singapore, Asia/Taipei, Asia/Ujung Pandang, Asia/Ulaanbaatar, Asia/Ulan Bator, Asia/Urumqi, Australia/Perth, Australia/West, CTT, Etc/GMT-8, Hongkong, PRC, Singapore
 241   32400 | Asia/Choibalsan, Asia/Dili, Asia/Jayapura, Asia/Pyongyang, Asia/Seoul, Asia/Tokyo, -Asia/Yakutsk, Etc/GMT-9, JST, Japan, Pacific/Palau, ROK
 242   34200 | ACT, -Australia/Adelaide, -Australia/Broken Hill, Australia/Darwin, Australia/North, -Australia/South, -Australia/Yancowinna
 243   36000 | -AET, Antarctica/DumontDUrville, -Asia/Sakhalin, -Asia/Vladivostok, -Australia/ACT, Australia/Brisbane, -Australia/Canberra, -Australia/Hobart, Australia/Lindeman, -Australia/Melbourne, -Australia/NSW, Australia/Queensland, -Australia/Sydney, -Australia/Tasmania, -Australia/Victoria, Etc/GMT-10, Pacific/Guam, Pacific/Port Moresby, Pacific/Saipan, Pacific/Truk, Pacific/Yap
 244   37800 | -Australia/LHI, -Australia/Lord Howe
 245   39600 | -Asia/Magadan, Etc/GMT-11, Pacific/Efate, Pacific/Guadalcanal, Pacific/Kosrae, Pacific/Noumea, Pacific/Ponape, SST
 246   41400 | Pacific/Norfolk
 247   43200 | -Antarctica/McMurdo, -Antarctica/South Pole, -Asia/Anadyr, -Asia/Kamchatka, Etc/GMT-12, Kwajalein, -NST, -NZ, -Pacific/Auckland, Pacific/Fiji, Pacific/Funafuti, Pacific/Kwajalein, Pacific/Majuro, Pacific/Nauru, Pacific/Tarawa, Pacific/Wake, Pacific/Wallis
 248   45900 | -NZ-CHAT, -Pacific/Chatham
 249   46800 | Etc/GMT-13, Pacific/Enderbury, Pacific/Tongatapu
 250   50400 | Etc/GMT-14, Pacific/Kiritimati', null, 'localize/timezone');
 251  
 252              $this->zones = array();
 253              foreach (explode("\n", $zones) as $zone){
 254                  list($offset, $places) = explode('|', $zone);
 255                  $offset = intval($offset);
 256                  $places = array_map('trim', array_diff(explode(',', $places.','), array('')));
 257                  foreach ($places as $k=>$place){
 258                      if($place[0] == '-'){
 259                          $places[$k] = trim($place,'-');
 260                          $this->dst_zones[] = $places[$k];
 261                      }
 262                  }
 263                  sort($places);
 264                  foreach ($places as $place){
 265                      $this->zones[$place] = $offset;
 266                  }
 267              }
 268  
 269          }
 270          return $this->zones;
 271      }
 272  
 273      /**
 274      * Return an array of all AkTimeZone objects. There are multiple AkTimeZone objects
 275      * per time zone, in many cases, to make it easier for users to find their own time zone.
 276      */
 277      function &all()
 278      {
 279          $TimeZone = new AkTimeZone();
 280          $time_zones = $TimeZone->getTimezones();
 281          $dst_zones = $TimeZone->dst_zones;
 282          $Zones = array();
 283          foreach ($time_zones as $name => $offset){
 284              $Zones[] = $TimeZone->create($name, $offset, $time_zones, $dst_zones);
 285          }
 286          return $Zones;
 287      }
 288  }
 289  
 290  defined('AK_DEFAULT_TIMEZONE') ? null : define('AK_DEFAULT_TIMEZONE', 'UTC');
 291  
 292  function_exists('date_default_timezone_set') ?  date_default_timezone_set(AK_DEFAULT_TIMEZONE) : @putenv('TZ='.AK_DEFAULT_TIMEZONE);
 293  
 294  if(!defined('AK_UTC_OFFSET')){
 295      $_AkCurrentZone = new AkTimeZone();
 296      $_AkCurrentZone = $_AkCurrentZone->create(AK_DEFAULT_TIMEZONE);
 297      define('AK_UTC_OFFSET', $_AkCurrentZone->utc_offset);
 298      unset($_AkCurrentZone);
 299  }
 300  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6