[limb-svn] r6533 - in 3.x/trunk/limb/datetime: . src tests/cases

svn at limb-project.com svn at limb-project.com
Wed Nov 21 23:03:25 MSK 2007


Author: pachanga
Date: 2007-11-21 23:03:24 +0300 (Wed, 21 Nov 2007)
New Revision: 6533
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6533

Added:
   3.x/trunk/limb/datetime/src/lmbDateTime.class.php
   3.x/trunk/limb/datetime/src/lmbDateTimePeriod.class.php
   3.x/trunk/limb/datetime/tests/cases/lmbDateTimePeriodTest.class.php
   3.x/trunk/limb/datetime/tests/cases/lmbDateTimeTest.class.php
Modified:
   3.x/trunk/limb/datetime/common.inc.php
   3.x/trunk/limb/datetime/src/lmbDate.class.php
   3.x/trunk/limb/datetime/src/lmbDatePeriod.class.php
   3.x/trunk/limb/datetime/src/lmbDateTimeZone.class.php
   3.x/trunk/limb/datetime/src/lmbTimePeriod.class.php
   3.x/trunk/limb/datetime/tests/cases/lmbDateTest.class.php
   3.x/trunk/limb/datetime/tests/cases/lmbTimePeriodTest.class.php
Log:
-- starting lmbDate refactoring - adding lmbDateTime class(simply copying lmbDate), BC preserved

Modified: 3.x/trunk/limb/datetime/common.inc.php
===================================================================
--- 3.x/trunk/limb/datetime/common.inc.php	2007-11-20 15:55:48 UTC (rev 6532)
+++ 3.x/trunk/limb/datetime/common.inc.php	2007-11-21 20:03:24 UTC (rev 6533)
@@ -1,16 +1,16 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-/**
- * @package datetime
- * @version $Id$
- */
-require_once('limb/core/common.inc.php');
-
-
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+/**
+ * @package datetime
+ * @version $Id$
+ */
+require_once('limb/core/common.inc.php');
+
+

Modified: 3.x/trunk/limb/datetime/src/lmbDate.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbDate.class.php	2007-11-20 15:55:48 UTC (rev 6532)
+++ 3.x/trunk/limb/datetime/src/lmbDate.class.php	2007-11-21 20:03:24 UTC (rev 6533)
@@ -1,673 +1,673 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-lmb_require('limb/core/src/lmbObject.class.php');
-
-/**
- * class lmbDate.
- *
- * @package datetime
- * @version $Id$
- */
-class lmbDate extends lmbObject
-{
-  const MINUTE = 60;
-  const HOUR = 3600;
-  const DAY = 86400;
-  const WEEK = 604800;
-  
-  //YYYY-MM-DD HH:MM:SS timezone
-  const DATE_ISO_REGEX = '~^(([0-9]{4})-([0-9]{2})-([0-9]{2}))?((?(1)\s+)([0-9]{2}):([0-9]{2}):?([0-9]{2})?)?$~';
-
-  /**
-   * Defines what day starts the week.
-   * Monday (1) is the international standard, Sunday (0) is used in US.
-   * @see setWeekStartsAt()
-   */
-  static protected $week_starts_at = 1;
-
-  protected $year = 0;
-  protected $month = 0;
-  protected $day = 0;
-  protected $hour = 0;
-  protected $minute = 0;
-  protected $second = 0;
-  protected $tz = '';
-
-  function __construct($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
-  {
-    if(func_num_args() > 2)
-    {
-      $this->year   = (int)$year_or_date;
-      $this->month  = (int)$month_or_tz;
-      $this->day    = (int)$day;
-      $this->hour   = (int)$hour;
-      $this->minute = (int)$minute;
-      $this->second = (int)$second;
-      $this->tz     = $tz;
-    }
-    elseif(is_a($year_or_date, 'lmbDate'))
-    {
-      $this->_copy($year_or_date);
-    }
-    elseif(is_numeric($year_or_date))
-    {
-      $this->_setByStamp($year_or_date);
-      $this->tz = $month_or_tz;
-    }
-    elseif(is_string($year_or_date))
-    {
-      $this->_setByString($year_or_date);
-      $this->tz = $month_or_tz;
-    }
-    else
-    {
-      $this->_setByStamp(time());
-      $this->tz = $month_or_tz;
-    }
-
-    if(!$this->isValid())
-    {
-      $args = func_get_args();
-      throw new lmbException("Could not create date using args", $args);
-    }
-  }
-
-  /**
-   * Wrapper around constructor
-   * 
-   * It can be useful since the following is not allowed in PHP 'new lmbDate(..)->addDay(..)->'
-   *
-   * @param integer $year_or_date
-   * @param integer $month_or_tz
-   * @param integer $day
-   * @param integer $hour
-   * @param integer $minute
-   * @param integer $second
-   * @param string $tz
-   * @return lmbDate
-   */
-  static function create($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
-  {
-    if(func_num_args() > 2)
-      return new self($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
-    else
-      return new self($year_or_date, $month_or_tz);
-  }
-
-  static function createByDays($days)
-  {
-    $days   -= 1721119;
-    $century = floor((4 * $days - 1) / 146097);
-    $days    = floor(4 * $days - 1 - 146097 * $century);
-    $day     = floor($days / 4);
-
-    $year    = floor((4 * $day +  3) / 1461);
-    $day     = floor(4 * $day +  3 - 1461 * $year);
-    $day     = floor(($day +  4) / 4);
-
-    $month   = floor((5 * $day - 3) / 153);
-    $day     = floor(5 * $day - 3 - 153 * $month);
-    $day     = floor(($day +  5) /  5);
-
-    if($month < 10)
-    {
-      $month +=3;
-    }
-    else
-    {
-      $month -=9;
-      if($year++ == 99)
-      {
-        $year = 0;
-        $century++;
-      }
-    }
-
-    $century = sprintf('%02d', $century);
-    $year    = sprintf('%02d', $year);
-    return new self($century . $year, $month, $day);
-  }
-
-  static function setWeekStartsAt($n)
-  {
-    self :: $week_starts_at = $n;
-  }
-
-  static function getWeekStartsAt()
-  {
-    return self :: $week_starts_at;
-  }
-
-  static function stampToIso($stamp)
-  {
-    $date = new self((int)$stamp);
-    return $date->getIsoDate();
-  }
-  
-  static function stampToShortIso($stamp)
-  {
-    $date = new $class((int)$stamp);
-    return $date->getIsoShortDate();
-  }
-  
-  function _createTimeZoneObject($code=null)
-  {
-    lmb_require('limb/datetime/src/lmbDateTimeZone.class.php');
-
-    if(!$code)
-      return lmbDateTimeZone::getDefault();
-    else
-      return new lmbDateTimeZone($code);
-  }
-
-  function isValid()
-  {
-    if($this->year < 0) return false;
-    if($this->month < 0 || $this->month > 12) return false;
-    if($this->day < 0 || $this->day > 31) return false;
-    if($this->hour < 0 || $this->hour > 23) return false;
-    if($this->minute < 0 || $this->minute > 59) return false;
-    if($this->second < 0 || $this->second > 59) return false;
-
-    //dirty hack for checkdate...
-    return checkdate($this->month ? $this->month : 1,
-                     $this->day ? $this->day : 1,
-                     $this->year ? $this->year : 1);
-  }
-
-  static function validate($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
-  {
-    try
-    {
-      if(func_num_args() > 2)
-        new self($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
-      else
-        new self($year_or_date, $month_or_tz);
-      return true;
-    }
-    catch(lmbException $e)
-    {
-      return false;
-    }
-  }
-
-  protected function _setByString($string)
-  {
-    if(!preg_match(self :: DATE_ISO_REGEX, trim($string), $regs))
-      throw new lmbException("Could not setup date using string '$string'");
-
-    if(isset($regs[1]))
-    {
-      $this->year   = (int)$regs[2];
-      $this->month  = (int)$regs[3];
-      $this->day    = (int)$regs[4];
-    }
-
-    if(isset($regs[5]))
-    {
-      $this->hour   = (int)$regs[6];
-      $this->minute = (int)$regs[7];
-      if(isset($regs[8]))
-        $this->second = (int)$regs[8];
-    }
-  }
-
-  protected function _setByStamp($time)
-  {
-    if(!$arr = @getdate($time))
-      throw new lmbException("Could not setup date using stamp'$time'");
-
-    $this->year   = $arr['year'];
-    $this->month  = $arr['mon'];
-    $this->day    = $arr['mday'];
-    $this->hour   = $arr['hours'];
-    $this->minute = $arr['minutes'];
-    $this->second = $arr['seconds'];
-  }
-
-  protected function _copy($date)
-  {
-    $this->year = $date->getYear();
-    $this->month = $date->getMonth();
-    $this->day = $date->getDay();
-    $this->hour = $date->getHour();
-    $this->minute = $date->getMinute();
-    $this->second = $date->getSecond();
-    $this->tz = $date->getTimeZone();
-  }
-
-  function getStamp()
-  {
-    //temporary ugly hack for unspecified year
-    if(!$this->year)
-      return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day);
-    else
-      return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
-  }
-
-  function date($format)
-  {
-    return date($format, $this->getStamp());
-  }
-
-  function strftime($format)
-  {
-    return strftime($format, $this->getStamp());
-  }
-
-  function getIsoDate($with_seconds = true)
-  {
-    return sprintf($with_seconds ? '%04d-%02d-%02d %02d:%02d:%02d' : '%04d-%02d-%02d %02d:%02d',
-                   $this->getYear(), $this->getMonth(), $this->getDay(),
-                   $this->getHour(), $this->getMinute(), $this->getSecond());
-  }
-
-  function getIsoShortDate()
-  {
-    return sprintf('%04d-%02d-%02d',
-                   $this->getYear(), $this->getMonth(), $this->getDay());
-  }
-
-  function getIsoTime($with_seconds = true)
-  {
-    return sprintf($with_seconds ? '%02d:%02d:%02d' : '%02d:%02d',
-                   $this->getHour(), $this->getMinute(), $this->getSecond());
-  }
-
-  function getIsoShortTime()
-  {
-    return $this->getIsoTime(false);
-  }
-
-  function toString()
-  {
-    return $this->getIsoDate();
-  }
-
-  function isInDaylightTime()
-  {
-    return $this->getTimeZoneObject()->inDaylightTime($this);
-  }
-
-  function toUTC()
-  {
-    $tz = $this->getTimeZoneObject();
-
-    if($tz->getOffset($this) > 0)
-      $date = $this->addSecond(-1 * intval($tz->getOffset($this) / 1000));
-    else
-      $date = $this->addSecond(intval(abs($tz->getOffset($this)) / 1000));
-
-    return $date->setTimeZone('UTC');
-  }
-
-  /**
-   * Compares object with $d date object.
-   * return int 0 if the dates are equal, -1 if is before, 1 if is after than $d
-   */
-  function compare($d)
-  {
-    if(!$d instanceof lmbDate)
-      throw new lmbException("Wrong date argument", array('arg' => $d));
-
-    $s1 = $this->getStamp();
-    $s2 = $d->getStamp();
-
-    if($s1 > $s2)
-      return 1;
-    elseif($s2 > $s1)
-      return -1;
-    else
-      return 0;
-  }
-
-  function isBefore($when, $use_time_zone=false)
-  {
-    if($this->compare($when, $use_time_zone) == -1)
-      return true;
-    else
-      return false;
-  }
-
-  function isAfter($when, $use_time_zone=false)
-  {
-    if($this->compare($when, $use_time_zone) == 1)
-      return true;
-    else
-      return false;
-  }
-
-  function isEqual($when, $use_time_zone=false)
-  {
-    if($this->compare($when, $use_time_zone) == 0)
-      return true;
-    else
-      return false;
-  }
-
-  function isEqualDate($when)
-  {
-    return $this->stripTime()->isEqual($when->stripTime());
-  }
-
-  function isLeapYear()
-  {
-    return (($this->year % 4 == 0 &&  $this->year % 100 != 0) ||  $this->year % 400 == 0);
-  }
-
-  function getDayOfYear()
-  {
-    $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
-
-    $julian = ($days[$this->month - 1] + $this->day);
-
-    if($this->month > 2 &&  $this->isLeapYear())
-      $julian++;
-
-    return $julian;
-  }
-
-  function getDayOfWeek()
-  {
-    return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), self :: $week_starts_at);
-  }
-
-  function getIntlDayOfWeek()
-  {
-    return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), 1);
-  }
-
-  function getPhpDayOfWeek()
-  {
-    $year = $this->year;
-    $month = $this->month;
-    $day = $this->day;
-
-    if(1901 < $year && $year < 2038)
-      return (int)date('w', mktime(0, 0, 0, $month, $day, $year));
-
-    if($month > 2)
-    {
-      $month -= 2;
-    }
-    else
-    {
-      $month += 10;
-      $year--;
-    }
-
-    $day = (floor((13 * $month - 1) / 5) +
-            $day + ($year % 100) +
-            floor(($year % 100) / 4) +
-            floor(($year / 100) / 4) - 2 *
-            floor($year / 100) + 77);
-
-    return $day - 7 * floor($day / 7);
-  }
-
-  protected function _correctDayOfWeek($dow, $week_starts_at)
-  {
-    if($week_starts_at == 0)
-      return $dow;
-
-    if($dow == 0)
-      return 6;
-    return $dow - 1;
-  }
-
-  function getBeginOfDay()
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, $this->tz);
-  }
-
-  function getEndOfDay()
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, 23, 59, 59, $this->tz);
-  }
-
-  function getBeginOfWeek()
-  {
-    $this_weekday = $this->getPhpDayOfWeek();
-    $interval = (7 - self :: $week_starts_at + $this_weekday) % 7;
-    return lmbDate :: createByDays($this->getDateDays() - $interval);
-  }
-
-  function getEndOfWeek()
-  {
-    $this_weekday = $this->getPhpDayOfWeek();
-    $interval = (6 + self :: $week_starts_at - $this_weekday) % 7;
-    return lmbDate :: createByDays($this->getDateDays() + $interval);
-  }
-
-  function getBeginOfMonth()
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, 1, $this->tz);
-  }
-
-  function getEndOfMonth()
-  {
-    return $this->setDay(1)->addMonth(1)->addDay(-1)->getEndOfDay();
-  }
-
-  function getBeginOfYear()
-  {
-    $class = get_class($this);
-    return new $class($this->year, 1, 1, $this->tz);
-  }
-
-  function getEndOfYear()
-  {
-    $class = get_class($this);
-    return new $class($this->year, 12, 31, 23, 59, 59, $this->tz);
-  }
-
-  function getWeekOfYear()
-  {
-    $day = $this->day;
-    $month = $this->month;
-    $year = $this->year;
-
-    if((1901 < $year) && ($year < 2038))
-    {
-      $res  = (int)date('W', mktime(0, 0, 0, $month, $day, $year));
-      if($res > 52) //bug in PHP date???
-        return $res % 52;
-      return $res;
-    }
-
-    $dayofweek = $this->getPhpDayOfWeek();
-    $firstday  = self :: create($year, 1, 1)->getPhpDayOfWeek();
-    if(($month == 1) && (($firstday < 1) || ($firstday > 4)) && ($day < 4))
-    {
-      $firstday  = self :: create($year - 1, 1, 1)->getPhpDayOfWeek();
-      $month     = 12;
-      $day       = 31;
-    }
-    elseif(($month == 12) && ((self :: create($year + 1, 1, 1)->getPhpDayOfWeek() < 5) &&
-            (self :: create($year + 1, 1, 1)->getPhpDayOfWeek() > 0)))
-        return 1;
-
-    return intval(((self :: create($year, 1, 1)->getPhpDayOfWeek() < 5) && (self :: create($year, 1, 1)->getPhpDayOfWeek() > 0)) +
-           4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256);
-  }
-
-  function getDateDays()
-  {
-    $century = (int)substr("{$this->year}", 0, 2);
-    $year = (int)substr("{$this->year}", 2, 2);
-    $month = $this->month;
-    $day = $this->day;
-
-    if($month > 2)
-      $month -= 3;
-    else
-    {
-      $month += 9;
-      if($year)
-        $year--;
-      else
-      {
-        $year = 99;
-        $century --;
-      }
-    }
-    return (
-        floor((146097 * $century) / 4) +
-        floor((1461 * $year) / 4) +
-        floor((153 * $month + 2) / 5) +
-        $day + 1721119);
-  }
-
-  function getYear()
-  {
-    return $this->year;
-  }
-
-  function getMonth()
-  {
-    return $this->month;
-  }
-
-  function getDay()
-  {
-    return $this->day;
-  }
-
-  function getHour()
-  {
-    return $this->hour;
-  }
-
-  function getMinute()
-  {
-    return $this->minute;
-  }
-
-  function getSecond()
-  {
-    return $this->second;
-  }
-
-  function getTimeZoneObject()
-  {
-    return $this->_createTimeZoneObject($this->tz);
-  }
-
-  function getTimeZone()
-  {
-    return $this->tz;
-  }
-
-  function setYear($y)
-  {
-    $class = get_class($this);
-    return new $class($y, $this->month, $this->day, $this->hour, $this->minute, $this->second, $this->tz);
-  }
-
-  function setMonth($m)
-  {
-    $class = get_class($this);
-    return new $class($this->year, $m, $this->day, $this->hour, $this->minute, $this->second, $this->tz);
-  }
-
-  function setDay($d)
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $d, $this->hour, $this->minute, $this->second, $this->tz);
-  }
-
-  function setHour($h)
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, $h, $this->minute, $this->second, $this->tz);
-  }
-
-  function setMinute($m)
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, $this->hour, $m, $this->second, $this->tz);
-  }
-
-  function setSecond($s)
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, $this->hour, $this->minute, $s, $this->tz);
-  }
-
-  function setTimeZone($tz)
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, $this->hour, $this->minute, $this->second, $tz);
-  }
-
-  function addYear($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year + $n));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function addMonth($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month + $n, $this->day, $this->year));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function addWeek($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + ($n * 7), $this->year));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function addDay($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $n, $this->year));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function addHour($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour + $n, $this->minute, $this->second, $this->month, $this->day, $this->year));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function addMinute($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour, $this->minute + $n, $this->second, $this->month, $this->day, $this->year));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function addSecond($n=1)
-  {
-    $class = get_class($this);
-    $date = new $class(mktime($this->hour, $this->minute, $this->second + $n, $this->month, $this->day, $this->year));
-    return $date->setTimeZone($this->tz);
-  }
-
-  function stripTime()
-  {
-    $class = get_class($this);
-    return new $class($this->year, $this->month, $this->day, 0, 0, 0, $this->tz);
-  }
-
-  function stripDate()
-  {
-    $class = get_class($this);
-    return new $class(null, null, null, $this->hour, $this->minute, $this->second, $this->tz);
-  }
-}
-
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+lmb_require('limb/core/src/lmbObject.class.php');
+
+/**
+ * class lmbDate.
+ *
+ * @package datetime
+ * @version $Id$
+ */
+class lmbDate extends lmbObject
+{
+  const MINUTE = 60;
+  const HOUR = 3600;
+  const DAY = 86400;
+  const WEEK = 604800;
+  
+  //YYYY-MM-DD HH:MM:SS timezone
+  const DATE_ISO_REGEX = '~^(([0-9]{4})-([0-9]{2})-([0-9]{2}))?((?(1)\s+)([0-9]{2}):([0-9]{2}):?([0-9]{2})?)?$~';
+
+  /**
+   * Defines what day starts the week.
+   * Monday (1) is the international standard, Sunday (0) is used in US.
+   * @see setWeekStartsAt()
+   */
+  static protected $week_starts_at = 1;
+
+  protected $year = 0;
+  protected $month = 0;
+  protected $day = 0;
+  protected $hour = 0;
+  protected $minute = 0;
+  protected $second = 0;
+  protected $tz = '';
+
+  function __construct($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
+  {
+    if(func_num_args() > 2)
+    {
+      $this->year   = (int)$year_or_date;
+      $this->month  = (int)$month_or_tz;
+      $this->day    = (int)$day;
+      $this->hour   = (int)$hour;
+      $this->minute = (int)$minute;
+      $this->second = (int)$second;
+      $this->tz     = $tz;
+    }
+    elseif(is_a($year_or_date, 'lmbDate'))
+    {
+      $this->_copy($year_or_date);
+    }
+    elseif(is_numeric($year_or_date))
+    {
+      $this->_setByStamp($year_or_date);
+      $this->tz = $month_or_tz;
+    }
+    elseif(is_string($year_or_date))
+    {
+      $this->_setByString($year_or_date);
+      $this->tz = $month_or_tz;
+    }
+    else
+    {
+      $this->_setByStamp(time());
+      $this->tz = $month_or_tz;
+    }
+
+    if(!$this->isValid())
+    {
+      $args = func_get_args();
+      throw new lmbException("Could not create date using args", $args);
+    }
+  }
+
+  /**
+   * Wrapper around constructor
+   * 
+   * It can be useful since the following is not allowed in PHP 'new lmbDate(..)->addDay(..)->'
+   *
+   * @param integer $year_or_date
+   * @param integer $month_or_tz
+   * @param integer $day
+   * @param integer $hour
+   * @param integer $minute
+   * @param integer $second
+   * @param string $tz
+   * @return lmbDate
+   */
+  static function create($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
+  {
+    if(func_num_args() > 2)
+      return new self($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
+    else
+      return new self($year_or_date, $month_or_tz);
+  }
+
+  static function createByDays($days)
+  {
+    $days   -= 1721119;
+    $century = floor((4 * $days - 1) / 146097);
+    $days    = floor(4 * $days - 1 - 146097 * $century);
+    $day     = floor($days / 4);
+
+    $year    = floor((4 * $day +  3) / 1461);
+    $day     = floor(4 * $day +  3 - 1461 * $year);
+    $day     = floor(($day +  4) / 4);
+
+    $month   = floor((5 * $day - 3) / 153);
+    $day     = floor(5 * $day - 3 - 153 * $month);
+    $day     = floor(($day +  5) /  5);
+
+    if($month < 10)
+    {
+      $month +=3;
+    }
+    else
+    {
+      $month -=9;
+      if($year++ == 99)
+      {
+        $year = 0;
+        $century++;
+      }
+    }
+
+    $century = sprintf('%02d', $century);
+    $year    = sprintf('%02d', $year);
+    return new self($century . $year, $month, $day);
+  }
+
+  static function setWeekStartsAt($n)
+  {
+    self :: $week_starts_at = $n;
+  }
+
+  static function getWeekStartsAt()
+  {
+    return self :: $week_starts_at;
+  }
+
+  static function stampToIso($stamp)
+  {
+    $date = new self((int)$stamp);
+    return $date->getIsoDate();
+  }
+  
+  static function stampToShortIso($stamp)
+  {
+    $date = new $class((int)$stamp);
+    return $date->getIsoShortDate();
+  }
+  
+  function _createTimeZoneObject($code=null)
+  {
+    lmb_require('limb/datetime/src/lmbDateTimeZone.class.php');
+
+    if(!$code)
+      return lmbDateTimeZone::getDefault();
+    else
+      return new lmbDateTimeZone($code);
+  }
+
+  function isValid()
+  {
+    if($this->year < 0) return false;
+    if($this->month < 0 || $this->month > 12) return false;
+    if($this->day < 0 || $this->day > 31) return false;
+    if($this->hour < 0 || $this->hour > 23) return false;
+    if($this->minute < 0 || $this->minute > 59) return false;
+    if($this->second < 0 || $this->second > 59) return false;
+
+    //dirty hack for checkdate...
+    return checkdate($this->month ? $this->month : 1,
+                     $this->day ? $this->day : 1,
+                     $this->year ? $this->year : 1);
+  }
+
+  static function validate($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
+  {
+    try
+    {
+      if(func_num_args() > 2)
+        new self($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
+      else
+        new self($year_or_date, $month_or_tz);
+      return true;
+    }
+    catch(lmbException $e)
+    {
+      return false;
+    }
+  }
+
+  protected function _setByString($string)
+  {
+    if(!preg_match(self :: DATE_ISO_REGEX, trim($string), $regs))
+      throw new lmbException("Could not setup date using string '$string'");
+
+    if(isset($regs[1]))
+    {
+      $this->year   = (int)$regs[2];
+      $this->month  = (int)$regs[3];
+      $this->day    = (int)$regs[4];
+    }
+
+    if(isset($regs[5]))
+    {
+      $this->hour   = (int)$regs[6];
+      $this->minute = (int)$regs[7];
+      if(isset($regs[8]))
+        $this->second = (int)$regs[8];
+    }
+  }
+
+  protected function _setByStamp($time)
+  {
+    if(!$arr = @getdate($time))
+      throw new lmbException("Could not setup date using stamp'$time'");
+
+    $this->year   = $arr['year'];
+    $this->month  = $arr['mon'];
+    $this->day    = $arr['mday'];
+    $this->hour   = $arr['hours'];
+    $this->minute = $arr['minutes'];
+    $this->second = $arr['seconds'];
+  }
+
+  protected function _copy($date)
+  {
+    $this->year = $date->getYear();
+    $this->month = $date->getMonth();
+    $this->day = $date->getDay();
+    $this->hour = $date->getHour();
+    $this->minute = $date->getMinute();
+    $this->second = $date->getSecond();
+    $this->tz = $date->getTimeZone();
+  }
+
+  function getStamp()
+  {
+    //temporary ugly hack for unspecified year
+    if(!$this->year)
+      return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day);
+    else
+      return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
+  }
+
+  function date($format)
+  {
+    return date($format, $this->getStamp());
+  }
+
+  function strftime($format)
+  {
+    return strftime($format, $this->getStamp());
+  }
+
+  function getIsoDate($with_seconds = true)
+  {
+    return sprintf($with_seconds ? '%04d-%02d-%02d %02d:%02d:%02d' : '%04d-%02d-%02d %02d:%02d',
+                   $this->getYear(), $this->getMonth(), $this->getDay(),
+                   $this->getHour(), $this->getMinute(), $this->getSecond());
+  }
+
+  function getIsoShortDate()
+  {
+    return sprintf('%04d-%02d-%02d',
+                   $this->getYear(), $this->getMonth(), $this->getDay());
+  }
+
+  function getIsoTime($with_seconds = true)
+  {
+    return sprintf($with_seconds ? '%02d:%02d:%02d' : '%02d:%02d',
+                   $this->getHour(), $this->getMinute(), $this->getSecond());
+  }
+
+  function getIsoShortTime()
+  {
+    return $this->getIsoTime(false);
+  }
+
+  function toString()
+  {
+    return $this->getIsoDate();
+  }
+
+  function isInDaylightTime()
+  {
+    return $this->getTimeZoneObject()->inDaylightTime($this);
+  }
+
+  function toUTC()
+  {
+    $tz = $this->getTimeZoneObject();
+
+    if($tz->getOffset($this) > 0)
+      $date = $this->addSecond(-1 * intval($tz->getOffset($this) / 1000));
+    else
+      $date = $this->addSecond(intval(abs($tz->getOffset($this)) / 1000));
+
+    return $date->setTimeZone('UTC');
+  }
+
+  /**
+   * Compares object with $d date object.
+   * return int 0 if the dates are equal, -1 if is before, 1 if is after than $d
+   */
+  function compare($d)
+  {
+    if(!$d instanceof lmbDate)
+      throw new lmbException("Wrong date argument", array('arg' => $d));
+
+    $s1 = $this->getStamp();
+    $s2 = $d->getStamp();
+
+    if($s1 > $s2)
+      return 1;
+    elseif($s2 > $s1)
+      return -1;
+    else
+      return 0;
+  }
+
+  function isBefore($when, $use_time_zone=false)
+  {
+    if($this->compare($when, $use_time_zone) == -1)
+      return true;
+    else
+      return false;
+  }
+
+  function isAfter($when, $use_time_zone=false)
+  {
+    if($this->compare($when, $use_time_zone) == 1)
+      return true;
+    else
+      return false;
+  }
+
+  function isEqual($when, $use_time_zone=false)
+  {
+    if($this->compare($when, $use_time_zone) == 0)
+      return true;
+    else
+      return false;
+  }
+
+  function isEqualDate($when)
+  {
+    return $this->stripTime()->isEqual($when->stripTime());
+  }
+
+  function isLeapYear()
+  {
+    return (($this->year % 4 == 0 &&  $this->year % 100 != 0) ||  $this->year % 400 == 0);
+  }
+
+  function getDayOfYear()
+  {
+    $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
+
+    $julian = ($days[$this->month - 1] + $this->day);
+
+    if($this->month > 2 &&  $this->isLeapYear())
+      $julian++;
+
+    return $julian;
+  }
+
+  function getDayOfWeek()
+  {
+    return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), self :: $week_starts_at);
+  }
+
+  function getIntlDayOfWeek()
+  {
+    return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), 1);
+  }
+
+  function getPhpDayOfWeek()
+  {
+    $year = $this->year;
+    $month = $this->month;
+    $day = $this->day;
+
+    if(1901 < $year && $year < 2038)
+      return (int)date('w', mktime(0, 0, 0, $month, $day, $year));
+
+    if($month > 2)
+    {
+      $month -= 2;
+    }
+    else
+    {
+      $month += 10;
+      $year--;
+    }
+
+    $day = (floor((13 * $month - 1) / 5) +
+            $day + ($year % 100) +
+            floor(($year % 100) / 4) +
+            floor(($year / 100) / 4) - 2 *
+            floor($year / 100) + 77);
+
+    return $day - 7 * floor($day / 7);
+  }
+
+  protected function _correctDayOfWeek($dow, $week_starts_at)
+  {
+    if($week_starts_at == 0)
+      return $dow;
+
+    if($dow == 0)
+      return 6;
+    return $dow - 1;
+  }
+
+  function getBeginOfDay()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->tz);
+  }
+
+  function getEndOfDay()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, 23, 59, 59, $this->tz);
+  }
+
+  function getBeginOfWeek()
+  {
+    $this_weekday = $this->getPhpDayOfWeek();
+    $interval = (7 - self :: $week_starts_at + $this_weekday) % 7;
+    return lmbDate :: createByDays($this->getDateDays() - $interval);
+  }
+
+  function getEndOfWeek()
+  {
+    $this_weekday = $this->getPhpDayOfWeek();
+    $interval = (6 + self :: $week_starts_at - $this_weekday) % 7;
+    return lmbDate :: createByDays($this->getDateDays() + $interval);
+  }
+
+  function getBeginOfMonth()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, 1, $this->tz);
+  }
+
+  function getEndOfMonth()
+  {
+    return $this->setDay(1)->addMonth(1)->addDay(-1)->getEndOfDay();
+  }
+
+  function getBeginOfYear()
+  {
+    $class = get_class($this);
+    return new $class($this->year, 1, 1, $this->tz);
+  }
+
+  function getEndOfYear()
+  {
+    $class = get_class($this);
+    return new $class($this->year, 12, 31, 23, 59, 59, $this->tz);
+  }
+
+  function getWeekOfYear()
+  {
+    $day = $this->day;
+    $month = $this->month;
+    $year = $this->year;
+
+    if((1901 < $year) && ($year < 2038))
+    {
+      $res  = (int)date('W', mktime(0, 0, 0, $month, $day, $year));
+      if($res > 52) //bug in PHP date???
+        return $res % 52;
+      return $res;
+    }
+
+    $dayofweek = $this->getPhpDayOfWeek();
+    $firstday  = self :: create($year, 1, 1)->getPhpDayOfWeek();
+    if(($month == 1) && (($firstday < 1) || ($firstday > 4)) && ($day < 4))
+    {
+      $firstday  = self :: create($year - 1, 1, 1)->getPhpDayOfWeek();
+      $month     = 12;
+      $day       = 31;
+    }
+    elseif(($month == 12) && ((self :: create($year + 1, 1, 1)->getPhpDayOfWeek() < 5) &&
+            (self :: create($year + 1, 1, 1)->getPhpDayOfWeek() > 0)))
+        return 1;
+
+    return intval(((self :: create($year, 1, 1)->getPhpDayOfWeek() < 5) && (self :: create($year, 1, 1)->getPhpDayOfWeek() > 0)) +
+           4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256);
+  }
+
+  function getDateDays()
+  {
+    $century = (int)substr("{$this->year}", 0, 2);
+    $year = (int)substr("{$this->year}", 2, 2);
+    $month = $this->month;
+    $day = $this->day;
+
+    if($month > 2)
+      $month -= 3;
+    else
+    {
+      $month += 9;
+      if($year)
+        $year--;
+      else
+      {
+        $year = 99;
+        $century --;
+      }
+    }
+    return (
+        floor((146097 * $century) / 4) +
+        floor((1461 * $year) / 4) +
+        floor((153 * $month + 2) / 5) +
+        $day + 1721119);
+  }
+
+  function getYear()
+  {
+    return $this->year;
+  }
+
+  function getMonth()
+  {
+    return $this->month;
+  }
+
+  function getDay()
+  {
+    return $this->day;
+  }
+
+  function getHour()
+  {
+    return $this->hour;
+  }
+
+  function getMinute()
+  {
+    return $this->minute;
+  }
+
+  function getSecond()
+  {
+    return $this->second;
+  }
+
+  function getTimeZoneObject()
+  {
+    return $this->_createTimeZoneObject($this->tz);
+  }
+
+  function getTimeZone()
+  {
+    return $this->tz;
+  }
+
+  function setYear($y)
+  {
+    $class = get_class($this);
+    return new $class($y, $this->month, $this->day, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+
+  function setMonth($m)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $m, $this->day, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+
+  function setDay($d)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $d, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+
+  function setHour($h)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $h, $this->minute, $this->second, $this->tz);
+  }
+
+  function setMinute($m)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->hour, $m, $this->second, $this->tz);
+  }
+
+  function setSecond($s)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->hour, $this->minute, $s, $this->tz);
+  }
+
+  function setTimeZone($tz)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->hour, $this->minute, $this->second, $tz);
+  }
+
+  function addYear($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year + $n));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addMonth($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month + $n, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addWeek($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + ($n * 7), $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addDay($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $n, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addHour($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour + $n, $this->minute, $this->second, $this->month, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addMinute($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute + $n, $this->second, $this->month, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addSecond($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second + $n, $this->month, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function stripTime()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, 0, 0, 0, $this->tz);
+  }
+
+  function stripDate()
+  {
+    $class = get_class($this);
+    return new $class(null, null, null, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+}
+

Modified: 3.x/trunk/limb/datetime/src/lmbDatePeriod.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbDatePeriod.class.php	2007-11-20 15:55:48 UTC (rev 6532)
+++ 3.x/trunk/limb/datetime/src/lmbDatePeriod.class.php	2007-11-21 20:03:24 UTC (rev 6533)
@@ -17,8 +17,8 @@
  */
 class lmbDatePeriod
 {
-  var $start;
-  var $end;
+  protected $start;
+  protected $end;
 
   function __construct($start, $end)
   {
@@ -26,8 +26,8 @@
     $this->end = (is_object($end)) ? $end : new lmbDate($end);
 
     if($this->end->isBefore($this->start))
-      throw new lmbException('wrong period interval', array('start' => $this->start->toString(),
-                                                             'end' => $this->end->toString()));
+      throw new lmbException('Wrong period interval', array('start' => $this->start->toString(),
+                                                            'end' => $this->end->toString()));
   }
 
   function toString()

Added: 3.x/trunk/limb/datetime/src/lmbDateTime.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbDateTime.class.php	                        (rev 0)
+++ 3.x/trunk/limb/datetime/src/lmbDateTime.class.php	2007-11-21 20:03:24 UTC (rev 6533)
@@ -0,0 +1,673 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+lmb_require('limb/core/src/lmbObject.class.php');
+
+/**
+ * class lmbDateTime.
+ *
+ * @package datetime
+ * @version $Id: lmbDate.class.php 6532 2007-11-20 15:55:48Z serega $
+ */
+class lmbDateTime extends lmbObject
+{
+  const MINUTE = 60;
+  const HOUR = 3600;
+  const DAY = 86400;
+  const WEEK = 604800;
+  
+  //YYYY-MM-DD HH:MM:SS timezone
+  const DATE_ISO_REGEX = '~^(([0-9]{4})-([0-9]{2})-([0-9]{2}))?((?(1)\s+)([0-9]{2}):([0-9]{2}):?([0-9]{2})?)?$~';
+
+  /**
+   * Defines what day starts the week.
+   * Monday (1) is the international standard, Sunday (0) is used in US.
+   * @see setWeekStartsAt()
+   */
+  static protected $week_starts_at = 1;
+
+  protected $year = 0;
+  protected $month = 0;
+  protected $day = 0;
+  protected $hour = 0;
+  protected $minute = 0;
+  protected $second = 0;
+  protected $tz = '';
+
+  function __construct($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
+  {
+    if(func_num_args() > 2)
+    {
+      $this->year   = (int)$year_or_date;
+      $this->month  = (int)$month_or_tz;
+      $this->day    = (int)$day;
+      $this->hour   = (int)$hour;
+      $this->minute = (int)$minute;
+      $this->second = (int)$second;
+      $this->tz     = $tz;
+    }
+    elseif(is_a($year_or_date, 'lmbDateTime'))
+    {
+      $this->_copy($year_or_date);
+    }
+    elseif(is_numeric($year_or_date))
+    {
+      $this->_setByStamp($year_or_date);
+      $this->tz = $month_or_tz;
+    }
+    elseif(is_string($year_or_date))
+    {
+      $this->_setByString($year_or_date);
+      $this->tz = $month_or_tz;
+    }
+    else
+    {
+      $this->_setByStamp(time());
+      $this->tz = $month_or_tz;
+    }
+
+    if(!$this->isValid())
+    {
+      $args = func_get_args();
+      throw new lmbException("Could not create date using args", $args);
+    }
+  }
+
+  /**
+   * Wrapper around constructor
+   * 
+   * It can be useful since the following is not allowed in PHP 'new lmbDateTime(..)->addDay(..)->'
+   *
+   * @param integer $year_or_date
+   * @param integer $month_or_tz
+   * @param integer $day
+   * @param integer $hour
+   * @param integer $minute
+   * @param integer $second
+   * @param string $tz
+   * @return lmbDateTime
+   */
+  static function create($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
+  {
+    if(func_num_args() > 2)
+      return new self($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
+    else
+      return new self($year_or_date, $month_or_tz);
+  }
+
+  static function createByDays($days)
+  {
+    $days   -= 1721119;
+    $century = floor((4 * $days - 1) / 146097);
+    $days    = floor(4 * $days - 1 - 146097 * $century);
+    $day     = floor($days / 4);
+
+    $year    = floor((4 * $day +  3) / 1461);
+    $day     = floor(4 * $day +  3 - 1461 * $year);
+    $day     = floor(($day +  4) / 4);
+
+    $month   = floor((5 * $day - 3) / 153);
+    $day     = floor(5 * $day - 3 - 153 * $month);
+    $day     = floor(($day +  5) /  5);
+
+    if($month < 10)
+    {
+      $month +=3;
+    }
+    else
+    {
+      $month -=9;
+      if($year++ == 99)
+      {
+        $year = 0;
+        $century++;
+      }
+    }
+
+    $century = sprintf('%02d', $century);
+    $year    = sprintf('%02d', $year);
+    return new self($century . $year, $month, $day);
+  }
+
+  static function setWeekStartsAt($n)
+  {
+    self :: $week_starts_at = $n;
+  }
+
+  static function getWeekStartsAt()
+  {
+    return self :: $week_starts_at;
+  }
+
+  static function stampToIso($stamp)
+  {
+    $date = new self((int)$stamp);
+    return $date->getIsoDate();
+  }
+  
+  static function stampToShortIso($stamp)
+  {
+    $date = new $class((int)$stamp);
+    return $date->getIsoShortDate();
+  }
+  
+  function _createTimeZoneObject($code=null)
+  {
+    lmb_require('limb/datetime/src/lmbDateTimeZone.class.php');
+
+    if(!$code)
+      return lmbDateTimeZone::getDefault();
+    else
+      return new lmbDateTimeZone($code);
+  }
+
+  function isValid()
+  {
+    if($this->year < 0) return false;
+    if($this->month < 0 || $this->month > 12) return false;
+    if($this->day < 0 || $this->day > 31) return false;
+    if($this->hour < 0 || $this->hour > 23) return false;
+    if($this->minute < 0 || $this->minute > 59) return false;
+    if($this->second < 0 || $this->second > 59) return false;
+
+    //dirty hack for checkdate...
+    return checkdate($this->month ? $this->month : 1,
+                     $this->day ? $this->day : 1,
+                     $this->year ? $this->year : 1);
+  }
+
+  static function validate($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
+  {
+    try
+    {
+      if(func_num_args() > 2)
+        new self($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
+      else
+        new self($year_or_date, $month_or_tz);
+      return true;
+    }
+    catch(lmbException $e)
+    {
+      return false;
+    }
+  }
+
+  protected function _setByString($string)
+  {
+    if(!preg_match(self :: DATE_ISO_REGEX, trim($string), $regs))
+      throw new lmbException("Could not setup date using string '$string'");
+
+    if(isset($regs[1]))
+    {
+      $this->year   = (int)$regs[2];
+      $this->month  = (int)$regs[3];
+      $this->day    = (int)$regs[4];
+    }
+
+    if(isset($regs[5]))
+    {
+      $this->hour   = (int)$regs[6];
+      $this->minute = (int)$regs[7];
+      if(isset($regs[8]))
+        $this->second = (int)$regs[8];
+    }
+  }
+
+  protected function _setByStamp($time)
+  {
+    if(!$arr = @getdate($time))
+      throw new lmbException("Could not setup date using stamp'$time'");
+
+    $this->year   = $arr['year'];
+    $this->month  = $arr['mon'];
+    $this->day    = $arr['mday'];
+    $this->hour   = $arr['hours'];
+    $this->minute = $arr['minutes'];
+    $this->second = $arr['seconds'];
+  }
+
+  protected function _copy($date)
+  {
+    $this->year = $date->getYear();
+    $this->month = $date->getMonth();
+    $this->day = $date->getDay();
+    $this->hour = $date->getHour();
+    $this->minute = $date->getMinute();
+    $this->second = $date->getSecond();
+    $this->tz = $date->getTimeZone();
+  }
+
+  function getStamp()
+  {
+    //temporary ugly hack for unspecified year
+    if(!$this->year)
+      return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day);
+    else
+      return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
+  }
+
+  function date($format)
+  {
+    return date($format, $this->getStamp());
+  }
+
+  function strftime($format)
+  {
+    return strftime($format, $this->getStamp());
+  }
+
+  function getIsoDate($with_seconds = true)
+  {
+    return sprintf($with_seconds ? '%04d-%02d-%02d %02d:%02d:%02d' : '%04d-%02d-%02d %02d:%02d',
+                   $this->getYear(), $this->getMonth(), $this->getDay(),
+                   $this->getHour(), $this->getMinute(), $this->getSecond());
+  }
+
+  function getIsoShortDate()
+  {
+    return sprintf('%04d-%02d-%02d',
+                   $this->getYear(), $this->getMonth(), $this->getDay());
+  }
+
+  function getIsoTime($with_seconds = true)
+  {
+    return sprintf($with_seconds ? '%02d:%02d:%02d' : '%02d:%02d',
+                   $this->getHour(), $this->getMinute(), $this->getSecond());
+  }
+
+  function getIsoShortTime()
+  {
+    return $this->getIsoTime(false);
+  }
+
+  function toString()
+  {
+    return $this->getIsoDate();
+  }
+
+  function isInDaylightTime()
+  {
+    return $this->getTimeZoneObject()->inDaylightTime($this);
+  }
+
+  function toUTC()
+  {
+    $tz = $this->getTimeZoneObject();
+
+    if($tz->getOffset($this) > 0)
+      $date = $this->addSecond(-1 * intval($tz->getOffset($this) / 1000));
+    else
+      $date = $this->addSecond(intval(abs($tz->getOffset($this)) / 1000));
+
+    return $date->setTimeZone('UTC');
+  }
+
+  /**
+   * Compares object with $d date object.
+   * return int 0 if the dates are equal, -1 if is before, 1 if is after than $d
+   */
+  function compare($d)
+  {
+    if(!$d instanceof lmbDateTime)
+      throw new lmbException("Wrong date argument", array('arg' => $d));
+
+    $s1 = $this->getStamp();
+    $s2 = $d->getStamp();
+
+    if($s1 > $s2)
+      return 1;
+    elseif($s2 > $s1)
+      return -1;
+    else
+      return 0;
+  }
+
+  function isBefore($when, $use_time_zone=false)
+  {
+    if($this->compare($when, $use_time_zone) == -1)
+      return true;
+    else
+      return false;
+  }
+
+  function isAfter($when, $use_time_zone=false)
+  {
+    if($this->compare($when, $use_time_zone) == 1)
+      return true;
+    else
+      return false;
+  }
+
+  function isEqual($when, $use_time_zone=false)
+  {
+    if($this->compare($when, $use_time_zone) == 0)
+      return true;
+    else
+      return false;
+  }
+
+  function isEqualDate($when)
+  {
+    return $this->stripTime()->isEqual($when->stripTime());
+  }
+
+  function isLeapYear()
+  {
+    return (($this->year % 4 == 0 &&  $this->year % 100 != 0) ||  $this->year % 400 == 0);
+  }
+
+  function getDayOfYear()
+  {
+    $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
+
+    $julian = ($days[$this->month - 1] + $this->day);
+
+    if($this->month > 2 &&  $this->isLeapYear())
+      $julian++;
+
+    return $julian;
+  }
+
+  function getDayOfWeek()
+  {
+    return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), self :: $week_starts_at);
+  }
+
+  function getIntlDayOfWeek()
+  {
+    return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), 1);
+  }
+
+  function getPhpDayOfWeek()
+  {
+    $year = $this->year;
+    $month = $this->month;
+    $day = $this->day;
+
+    if(1901 < $year && $year < 2038)
+      return (int)date('w', mktime(0, 0, 0, $month, $day, $year));
+
+    if($month > 2)
+    {
+      $month -= 2;
+    }
+    else
+    {
+      $month += 10;
+      $year--;
+    }
+
+    $day = (floor((13 * $month - 1) / 5) +
+            $day + ($year % 100) +
+            floor(($year % 100) / 4) +
+            floor(($year / 100) / 4) - 2 *
+            floor($year / 100) + 77);
+
+    return $day - 7 * floor($day / 7);
+  }
+
+  protected function _correctDayOfWeek($dow, $week_starts_at)
+  {
+    if($week_starts_at == 0)
+      return $dow;
+
+    if($dow == 0)
+      return 6;
+    return $dow - 1;
+  }
+
+  function getBeginOfDay()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->tz);
+  }
+
+  function getEndOfDay()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, 23, 59, 59, $this->tz);
+  }
+
+  function getBeginOfWeek()
+  {
+    $this_weekday = $this->getPhpDayOfWeek();
+    $interval = (7 - self :: $week_starts_at + $this_weekday) % 7;
+    return self :: createByDays($this->getDateDays() - $interval);
+  }
+
+  function getEndOfWeek()
+  {
+    $this_weekday = $this->getPhpDayOfWeek();
+    $interval = (6 + self :: $week_starts_at - $this_weekday) % 7;
+    return self :: createByDays($this->getDateDays() + $interval);
+  }
+
+  function getBeginOfMonth()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, 1, $this->tz);
+  }
+
+  function getEndOfMonth()
+  {
+    return $this->setDay(1)->addMonth(1)->addDay(-1)->getEndOfDay();
+  }
+
+  function getBeginOfYear()
+  {
+    $class = get_class($this);
+    return new $class($this->year, 1, 1, $this->tz);
+  }
+
+  function getEndOfYear()
+  {
+    $class = get_class($this);
+    return new $class($this->year, 12, 31, 23, 59, 59, $this->tz);
+  }
+
+  function getWeekOfYear()
+  {
+    $day = $this->day;
+    $month = $this->month;
+    $year = $this->year;
+
+    if((1901 < $year) && ($year < 2038))
+    {
+      $res  = (int)date('W', mktime(0, 0, 0, $month, $day, $year));
+      if($res > 52) //bug in PHP date???
+        return $res % 52;
+      return $res;
+    }
+
+    $dayofweek = $this->getPhpDayOfWeek();
+    $firstday  = self :: create($year, 1, 1)->getPhpDayOfWeek();
+    if(($month == 1) && (($firstday < 1) || ($firstday > 4)) && ($day < 4))
+    {
+      $firstday  = self :: create($year - 1, 1, 1)->getPhpDayOfWeek();
+      $month     = 12;
+      $day       = 31;
+    }
+    elseif(($month == 12) && ((self :: create($year + 1, 1, 1)->getPhpDayOfWeek() < 5) &&
+            (self :: create($year + 1, 1, 1)->getPhpDayOfWeek() > 0)))
+        return 1;
+
+    return intval(((self :: create($year, 1, 1)->getPhpDayOfWeek() < 5) && (self :: create($year, 1, 1)->getPhpDayOfWeek() > 0)) +
+           4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256);
+  }
+
+  function getDateDays()
+  {
+    $century = (int)substr("{$this->year}", 0, 2);
+    $year = (int)substr("{$this->year}", 2, 2);
+    $month = $this->month;
+    $day = $this->day;
+
+    if($month > 2)
+      $month -= 3;
+    else
+    {
+      $month += 9;
+      if($year)
+        $year--;
+      else
+      {
+        $year = 99;
+        $century --;
+      }
+    }
+    return (
+        floor((146097 * $century) / 4) +
+        floor((1461 * $year) / 4) +
+        floor((153 * $month + 2) / 5) +
+        $day + 1721119);
+  }
+
+  function getYear()
+  {
+    return $this->year;
+  }
+
+  function getMonth()
+  {
+    return $this->month;
+  }
+
+  function getDay()
+  {
+    return $this->day;
+  }
+
+  function getHour()
+  {
+    return $this->hour;
+  }
+
+  function getMinute()
+  {
+    return $this->minute;
+  }
+
+  function getSecond()
+  {
+    return $this->second;
+  }
+
+  function getTimeZoneObject()
+  {
+    return $this->_createTimeZoneObject($this->tz);
+  }
+
+  function getTimeZone()
+  {
+    return $this->tz;
+  }
+
+  function setYear($y)
+  {
+    $class = get_class($this);
+    return new $class($y, $this->month, $this->day, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+
+  function setMonth($m)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $m, $this->day, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+
+  function setDay($d)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $d, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+
+  function setHour($h)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $h, $this->minute, $this->second, $this->tz);
+  }
+
+  function setMinute($m)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->hour, $m, $this->second, $this->tz);
+  }
+
+  function setSecond($s)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->hour, $this->minute, $s, $this->tz);
+  }
+
+  function setTimeZone($tz)
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, $this->hour, $this->minute, $this->second, $tz);
+  }
+
+  function addYear($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year + $n));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addMonth($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month + $n, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addWeek($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + ($n * 7), $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addDay($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $n, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addHour($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour + $n, $this->minute, $this->second, $this->month, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addMinute($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute + $n, $this->second, $this->month, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function addSecond($n=1)
+  {
+    $class = get_class($this);
+    $date = new $class(mktime($this->hour, $this->minute, $this->second + $n, $this->month, $this->day, $this->year));
+    return $date->setTimeZone($this->tz);
+  }
+
+  function stripTime()
+  {
+    $class = get_class($this);
+    return new $class($this->year, $this->month, $this->day, 0, 0, 0, $this->tz);
+  }
+
+  function stripDate()
+  {
+    $class = get_class($this);
+    return new $class(null, null, null, $this->hour, $this->minute, $this->second, $this->tz);
+  }
+}
+

Added: 3.x/trunk/limb/datetime/src/lmbDateTimePeriod.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbDateTimePeriod.class.php	                        (rev 0)
+++ 3.x/trunk/limb/datetime/src/lmbDateTimePeriod.class.php	2007-11-21 20:03:24 UTC (rev 6533)
@@ -0,0 +1,80 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com 
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
+ */
+lmb_require('limb/datetime/src/lmbDateTime.class.php');
+lmb_require('limb/core/src/exception/lmbException.class.php');
+
+/**
+ * class lmbDateTimePeriod.
+ *
+ * @package datetime
+ * @version $Id: lmbDateTimePeriod.class.php 6243 2007-08-29 11:53:10Z pachanga $
+ */
+class lmbDateTimePeriod
+{
+  protected $start;
+  protected $end;
+
+  function __construct($start, $end)
+  {
+    $this->start = (is_object($start)) ? $start : new lmbDateTime($start);
+    $this->end = (is_object($end)) ? $end : new lmbDateTime($end);
+
+    if($this->end->isBefore($this->start))
+      throw new lmbException('Wrong period interval', array('start' => $this->start->toString(),
+                                                            'end' => $this->end->toString()));
+  }
+
+  function toString()
+  {
+    return $this->start->toString() . ' - ' . $this->end->toString();
+  }
+
+  function getDuration()
+  {
+    return $this->end->getStamp() - $this->start->getStamp();
+  }
+
+  function getStart()
+  {
+    return $this->start;
+  }
+
+  function getEnd()
+  {
+    return $this->end;
+  }
+
+  function isEqual($period)
+  {
+    return $this->start->isEqual($period->getStart()) &&
+           $this->end->isEqual($period->getEnd());
+  }
+
+  function includes($period)
+  {
+    return ($this->start->isBefore($period->getStart()) &&
+            $this->end->isAfter($period->getEnd()));
+  }
+
+  function isInside($period)
+  {
+    return $period->includes($this);
+  }
+
+  function intersects($period)
+  {
+    return $this->isEqual($period)
+           ||
+           ($this->start->isBefore($period->getStart()) && $this->end->isAfter($period->getStart()))
+           ||
+           ($this->start->isAfter($period->getStart()) && $this->start->isBefore($period->getEnd()));
+  }
+}
+
+

Modified: 3.x/trunk/limb/datetime/src/lmbDateTimeZone.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbDateTimeZone.class.php	2007-11-20 15:55:48 UTC (rev 6532)
+++ 3.x/trunk/limb/datetime/src/lmbDateTimeZone.class.php	2007-11-21 20:03:24 UTC (rev 6533)
@@ -1,3480 +1,3480 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-//inspired by PEAR::Date package
-
-/**
- * time_zone representation class, along with time zone information data.
- *
- * time_zone representation class, along with time zone information data.
- * The default timezone is set from the first valid timezone id found
- * in one of the following places, in this order:
- * 1) global $_DATE_TIMEZONE_DEFAULT
- * 2) system environment variable PHP_TZ
- * 3) system environment variable TZ
- * 4) the result of date('T')
- * If no valid timezone id is found, the default timezone is set to 'UTC'.
- * You may also manually set the default timezone by passing a valid id to
- * date_time_zone::set_default().
- *
- * This class includes time zone data (from zoneinfo) in the form of a global array, $_DATE_TIMEZONE_DATA.
- * @package datetime
- * @version $Id$
- */
-class lmbDateTimeZone
-{
-  var $id;
-  var $longname; //Long Name of this time zone (ie Central Standard Time)
-  var $shortname; //Short Name of this time zone (ie CST)
-  var $hasdst; //true if this time zone observes daylight savings time
-  var $dstlongname; //DST Long Name of this time zone
-  var $dstshortname; //DST Short Name of this timezone
-  var $offset; //offset, in milliseconds, of this timezone
-
-  var $default; //System Default Time Zone
-
-  function lmbDateTimeZone($id)
-  {
-    global $_DATE_TIMEZONE_DATA;
-
-    if (lmbDateTimeZone::isValidId($id))
-    {
-      $this->id = $id;
-      $this->longname = $_DATE_TIMEZONE_DATA[$id]['longname'];
-      $this->shortname = $_DATE_TIMEZONE_DATA[$id]['shortname'];
-      $this->offset = $_DATE_TIMEZONE_DATA[$id]['offset'];
-
-      if ($_DATE_TIMEZONE_DATA[$id]['hasdst'])
-      {
-        $this->hasdst = true;
-        $this->dstlongname = $_DATE_TIMEZONE_DATA[$id]['dstlongname'];
-        $this->dstshortname = $_DATE_TIMEZONE_DATA[$id]['dstshortname'];
-      }
-      else
-      {
-        $this->hasdst = false;
-        $this->dstlongname = $this->longname;
-        $this->dstshortname = $this->shortname;
-      }
-    }
-    else
-    {
-      $this->id = 'UTC';
-      $this->longname = $_DATE_TIMEZONE_DATA[$this->id]['longname'];
-      $this->shortname = $_DATE_TIMEZONE_DATA[$this->id]['shortname'];
-      $this->dstlongname = $this->longname;
-      $this->dstshortname = $this->shortname;
-      $this->hasdst = $_DATE_TIMEZONE_DATA[$this->id]['hasdst'];
-      $this->offset = $_DATE_TIMEZONE_DATA[$this->id]['offset'];
-    }
-  }
-
-  function getDefault()
-  {
-    global $_DATE_TIMEZONE_DEFAULT;
-    return new lmbDateTimeZone($_DATE_TIMEZONE_DEFAULT);
-  }
-
-  function setDefault($id)
-  {
-    global $_DATE_TIMEZONE_DEFAULT;
-    if (lmbDateTimeZone::isValidId($id))
-      $_DATE_TIMEZONE_DEFAULT = $id;
-  }
-
-  function isValidId($id)
-  {
-    global $_DATE_TIMEZONE_DATA;
-    if (isset($_DATE_TIMEZONE_DATA[$id]))
-      return true;
-    else
-      return false;
-  }
-
-  /**
-  * Is this time zone equal to another
-  */
-  function isEqual($tz)
-  {
-    if (strcasecmp($this->id, $tz->getId()) == 0)
-      return true;
-    else
-      return false;
-  }
-
-  /**
-  * Is this time zone equivalent to another
-  *
-  * Tests to see if this time zone is equivalent to
-  * a given time zone object.  Equivalence in this context
-  * is defined by the two time zones having an equal raw
-  * offset and an equal setting of "hasdst".  This is not true
-  * equivalence, as the two time zones may have different rules
-  * for the observance of DST, but this implementation does not
-  * know DST rules.
-  */
-  function isEquivalent($tz)
-  {
-    if ($this->offset == $tz->getRawOffset() &&  $this->hasdst == $tz->hasDaylightTime())
-      return true;
-    else
-      return false;
-  }
-
-  /**
-  * Returns true if this zone observes daylight savings time
-  */
-  function hasDaylightTime()
-  {
-    return $this->hasdst;
-  }
-
-  /**
-  * Is the given date/time in DST for this time zone
-  *
-  * Attempts to determine if a given date object represents a date/time
-  * that is in DST for this time zone.  WARNINGS: this basically attempts to
-  * "trick" the system into telling us if we're in DST for a given time zone.
-  * This uses putenv() which may not work in safe mode, and relies on unix time
-  * which is only valid for dates from 1970 to ~2038.  This relies on the
-  * underlying OS calls, so it may not work on Windows or on a system where
-  * zoneinfo is not installed or configured properly.
-  */
-  function inDaylightTime($date)
-  {
-    $env_tz = '';
-    if (getenv('TZ'))
-      $env_tz = getenv('TZ');
-
-    if($this->id)
-      putenv('TZ=' . $this->id);
-    $ltime = localtime($date->getStamp(), true);
-
-    if($env_tz)
-      putenv('TZ=' . $env_tz);
-
-    return $ltime['tm_isdst'];
-  }
-
-  /**
-  * Get the DST offset for this time zone
-  *
-  * Returns the DST offset of this time zone, in milliseconds,
-  * if the zone observes DST, zero otherwise.  Currently the
-  * DST offset is hard-coded to one hour.
-  */
-  function getDSTSavings()
-  {
-    if ($this->hasdst)
-      return 3600000;
-    else
-      return 0;
-  }
-
-  /**
-  * Get the DST-corrected offset to UTC for the given date
-  *
-  * Attempts to get the offset to UTC for a given date/time, taking into
-  * account daylight savings time, if the time zone observes it and if
-  * it is in effect.  Please see the WARNINGS on date_time_zone::in_daylight_time().
-  */
-  function getOffset($date)
-  {
-    if ($this->inDaylightTime($date))
-      return $this->offset + $this->getDSTSavings();
-    else
-      return $this->offset;
-  }
-
-  /**
-  * Returns the list of valid time zone id strings
-  */
-  function getAvailableIds()
-  {
-    global $_DATE_TIMEZONE_DATA;
-    return array_keys($_DATE_TIMEZONE_DATA);
-  }
-
-  /**
-  * Returns the time zone id  for this time zone, i.e. "America/Chicago"
-  */
-  function getId()
-  {
-    return $this->id;
-  }
-
-  /**
-  * Returns the long name for this time zone,
-  * i.e. "Central Standard Time"
-  */
-  function getLongName()
-  {
-    return $this->longname;
-  }
-
-  /**
-  * Returns the short name for this time zone, i.e. "CST"
-  */
-  function getShortName()
-  {
-    return $this->shortname;
-  }
-
-  /**
-  * Returns the DST long name for this time zone, i.e. "Central Daylight Time"
-  */
-  function getDSTLongName()
-  {
-    return $this->dstlongname;
-  }
-
-  /**
-  * Returns the DST short name for this time zone, i.e. "CDT"
-  */
-  function getDSTShortName()
-  {
-    return $this->dstshortname;
-  }
-
-  /**
-  * Returns the raw (non-DST-corrected) offset from UTC/GMT for this time zone
-  */
-  function getRawOffset()
-  {
-    return $this->offset;
-  }
-}
-
-$GLOBALS['_DATE_TIMEZONE_DATA'] = array(
-    'Etc/GMT+12' => array(
-        'offset' => -43200000,
-        'longname' => "GMT-12:00",
-        'shortname' => 'GMT-12:00',
-        'hasdst' => false ),
-    'Etc/GMT+11' => array(
-        'offset' => -39600000,
-        'longname' => "GMT-11:00",
-        'shortname' => 'GMT-11:00',
-        'hasdst' => false ),
-    'MIT' => array(
-        'offset' => -39600000,
-        'longname' => "West Samoa Time",
-        'shortname' => 'WST',
-        'hasdst' => false ),
-    'Pacific/Apia' => array(
-        'offset' => -39600000,
-        'longname' => "West Samoa Time",
-        'shortname' => 'WST',
-        'hasdst' => false ),
-    'Pacific/Midway' => array(
-        'offset' => -39600000,
-        'longname' => "Samoa Standard Time",
-        'shortname' => 'SST',
-        'hasdst' => false ),
-    'Pacific/Niue' => array(
-        'offset' => -39600000,
-        'longname' => "Niue Time",
-        'shortname' => 'NUT',
-        'hasdst' => false ),
-    'Pacific/Pago_Pago' => array(
-        'offset' => -39600000,
-        'longname' => "Samoa Standard Time",
-        'shortname' => 'SST',
-        'hasdst' => false ),
-    'Pacific/Samoa' => array(
-        'offset' => -39600000,
-        'longname' => "Samoa Standard Time",
-        'shortname' => 'SST',
-        'hasdst' => false ),
-    'US/Samoa' => array(
-        'offset' => -39600000,
-        'longname' => "Samoa Standard Time",
-        'shortname' => 'SST',
-        'hasdst' => false ),
-    'America/Adak' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii-Aleutian Standard Time",
-        'shortname' => 'HAST',
-        'hasdst' => true,
-        'dstlongname' => "Hawaii-Aleutian Daylight Time",
-        'dstshortname' => 'HADT' ),
-    'America/Atka' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii-Aleutian Standard Time",
-        'shortname' => 'HAST',
-        'hasdst' => true,
-        'dstlongname' => "Hawaii-Aleutian Daylight Time",
-        'dstshortname' => 'HADT' ),
-    'Etc/GMT+10' => array(
-        'offset' => -36000000,
-        'longname' => "GMT-10:00",
-        'shortname' => 'GMT-10:00',
-        'hasdst' => false ),
-    'HST' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii Standard Time",
-        'shortname' => 'HST',
-        'hasdst' => false ),
-    'Pacific/Fakaofo' => array(
-        'offset' => -36000000,
-        'longname' => "Tokelau Time",
-        'shortname' => 'TKT',
-        'hasdst' => false ),
-    'Pacific/Honolulu' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii Standard Time",
-        'shortname' => 'HST',
-        'hasdst' => false ),
-    'Pacific/Johnston' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii Standard Time",
-        'shortname' => 'HST',
-        'hasdst' => false ),
-    'Pacific/Rarotonga' => array(
-        'offset' => -36000000,
-        'longname' => "Cook Is. Time",
-        'shortname' => 'CKT',
-        'hasdst' => false ),
-    'Pacific/Tahiti' => array(
-        'offset' => -36000000,
-        'longname' => "Tahiti Time",
-        'shortname' => 'TAHT',
-        'hasdst' => false ),
-    'SystemV/HST10' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii Standard Time",
-        'shortname' => 'HST',
-        'hasdst' => false ),
-    'US/Aleutian' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii-Aleutian Standard Time",
-        'shortname' => 'HAST',
-        'hasdst' => true,
-        'dstlongname' => "Hawaii-Aleutian Daylight Time",
-        'dstshortname' => 'HADT' ),
-    'US/Hawaii' => array(
-        'offset' => -36000000,
-        'longname' => "Hawaii Standard Time",
-        'shortname' => 'HST',
-        'hasdst' => false ),
-    'Pacific/Marquesas' => array(
-        'offset' => -34200000,
-        'longname' => "Marquesas Time",
-        'shortname' => 'MART',
-        'hasdst' => false ),
-    'AST' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'America/Anchorage' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'America/Juneau' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'America/Nome' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'America/Yakutat' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'Etc/GMT+9' => array(
-        'offset' => -32400000,
-        'longname' => "GMT-09:00",
-        'shortname' => 'GMT-09:00',
-        'hasdst' => false ),
-    'Pacific/Gambier' => array(
-        'offset' => -32400000,
-        'longname' => "Gambier Time",
-        'shortname' => 'GAMT',
-        'hasdst' => false ),
-    'SystemV/YST9' => array(
-        'offset' => -32400000,
-        'longname' => "Gambier Time",
-        'shortname' => 'GAMT',
-        'hasdst' => false ),
-    'SystemV/YST9YDT' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'US/Alaska' => array(
-        'offset' => -32400000,
-        'longname' => "Alaska Standard Time",
-        'shortname' => 'AKST',
-        'hasdst' => true,
-        'dstlongname' => "Alaska Daylight Time",
-        'dstshortname' => 'AKDT' ),
-    'America/Dawson' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'America/Ensenada' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'America/Los_Angeles' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'America/Tijuana' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'America/Vancouver' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'America/Whitehorse' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'Canada/Pacific' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'Canada/Yukon' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'Etc/GMT+8' => array(
-        'offset' => -28800000,
-        'longname' => "GMT-08:00",
-        'shortname' => 'GMT-08:00',
-        'hasdst' => false ),
-    'Mexico/BajaNorte' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'PST' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'PST8PDT' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'Pacific/Pitcairn' => array(
-        'offset' => -28800000,
-        'longname' => "Pitcairn Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => false ),
-    'SystemV/PST8' => array(
-        'offset' => -28800000,
-        'longname' => "Pitcairn Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => false ),
-    'SystemV/PST8PDT' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'US/Pacific' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'US/Pacific-New' => array(
-        'offset' => -28800000,
-        'longname' => "Pacific Standard Time",
-        'shortname' => 'PST',
-        'hasdst' => true,
-        'dstlongname' => "Pacific Daylight Time",
-        'dstshortname' => 'PDT' ),
-    'America/Boise' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Cambridge_Bay' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Chihuahua' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Dawson_Creek' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => false ),
-    'America/Denver' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Edmonton' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Hermosillo' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => false ),
-    'America/Inuvik' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Mazatlan' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Phoenix' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => false ),
-    'America/Shiprock' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Yellowknife' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'Canada/Mountain' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'Etc/GMT+7' => array(
-        'offset' => -25200000,
-        'longname' => "GMT-07:00",
-        'shortname' => 'GMT-07:00',
-        'hasdst' => false ),
-    'MST' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'MST7MDT' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'Mexico/BajaSur' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'Navajo' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'PNT' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => false ),
-    'SystemV/MST7' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => false ),
-    'SystemV/MST7MDT' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'US/Arizona' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => false ),
-    'US/Mountain' => array(
-        'offset' => -25200000,
-        'longname' => "Mountain Standard Time",
-        'shortname' => 'MST',
-        'hasdst' => true,
-        'dstlongname' => "Mountain Daylight Time",
-        'dstshortname' => 'MDT' ),
-    'America/Belize' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Cancun' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Chicago' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Costa_Rica' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/El_Salvador' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Guatemala' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Managua' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Menominee' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Merida' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Mexico_City' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Monterrey' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/North_Dakota/Center' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Rainy_River' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Rankin_Inlet' => array(
-        'offset' => -21600000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Regina' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Swift_Current' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Tegucigalpa' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'America/Winnipeg' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'CST' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'CST6CDT' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'Canada/Central' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'Canada/East-Saskatchewan' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'Canada/Saskatchewan' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'Chile/EasterIsland' => array(
-        'offset' => -21600000,
-        'longname' => "Easter Is. Time",
-        'shortname' => 'EAST',
-        'hasdst' => true,
-        'dstlongname' => "Easter Is. Summer Time",
-        'dstshortname' => 'EASST' ),
-    'Etc/GMT+6' => array(
-        'offset' => -21600000,
-        'longname' => "GMT-06:00",
-        'shortname' => 'GMT-06:00',
-        'hasdst' => false ),
-    'Mexico/General' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'Pacific/Easter' => array(
-        'offset' => -21600000,
-        'longname' => "Easter Is. Time",
-        'shortname' => 'EAST',
-        'hasdst' => true,
-        'dstlongname' => "Easter Is. Summer Time",
-        'dstshortname' => 'EASST' ),
-    'Pacific/Galapagos' => array(
-        'offset' => -21600000,
-        'longname' => "Galapagos Time",
-        'shortname' => 'GALT',
-        'hasdst' => false ),
-    'SystemV/CST6' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => false ),
-    'SystemV/CST6CDT' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'US/Central' => array(
-        'offset' => -21600000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Bogota' => array(
-        'offset' => -18000000,
-        'longname' => "Colombia Time",
-        'shortname' => 'COT',
-        'hasdst' => false ),
-    'America/Cayman' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Detroit' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Eirunepe' => array(
-        'offset' => -18000000,
-        'longname' => "Acre Time",
-        'shortname' => 'ACT',
-        'hasdst' => false ),
-    'America/Fort_Wayne' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Grand_Turk' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Guayaquil' => array(
-        'offset' => -18000000,
-        'longname' => "Ecuador Time",
-        'shortname' => 'ECT',
-        'hasdst' => false ),
-    'America/Havana' => array(
-        'offset' => -18000000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'America/Indiana/Indianapolis' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Indiana/Knox' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Indiana/Marengo' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Indiana/Vevay' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Indianapolis' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Iqaluit' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Jamaica' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Kentucky/Louisville' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Kentucky/Monticello' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Knox_IN' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Lima' => array(
-        'offset' => -18000000,
-        'longname' => "Peru Time",
-        'shortname' => 'PET',
-        'hasdst' => false ),
-    'America/Louisville' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Montreal' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Nassau' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/New_York' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Nipigon' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Panama' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Pangnirtung' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Port-au-Prince' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'America/Porto_Acre' => array(
-        'offset' => -18000000,
-        'longname' => "Acre Time",
-        'shortname' => 'ACT',
-        'hasdst' => false ),
-    'America/Rio_Branco' => array(
-        'offset' => -18000000,
-        'longname' => "Acre Time",
-        'shortname' => 'ACT',
-        'hasdst' => false ),
-    'America/Thunder_Bay' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'Brazil/Acre' => array(
-        'offset' => -18000000,
-        'longname' => "Acre Time",
-        'shortname' => 'ACT',
-        'hasdst' => false ),
-    'Canada/Eastern' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'Cuba' => array(
-        'offset' => -18000000,
-        'longname' => "Central Standard Time",
-        'shortname' => 'CST',
-        'hasdst' => true,
-        'dstlongname' => "Central Daylight Time",
-        'dstshortname' => 'CDT' ),
-    'EST' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'EST5EDT' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'Etc/GMT+5' => array(
-        'offset' => -18000000,
-        'longname' => "GMT-05:00",
-        'shortname' => 'GMT-05:00',
-        'hasdst' => false ),
-    'IET' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'Jamaica' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'SystemV/EST5' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'SystemV/EST5EDT' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'US/East-Indiana' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'US/Eastern' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'US/Indiana-Starke' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => false ),
-    'US/Michigan' => array(
-        'offset' => -18000000,
-        'longname' => "Eastern Standard Time",
-        'shortname' => 'EST',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Daylight Time",
-        'dstshortname' => 'EDT' ),
-    'America/Anguilla' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Antigua' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Aruba' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Asuncion' => array(
-        'offset' => -14400000,
-        'longname' => "Paraguay Time",
-        'shortname' => 'PYT',
-        'hasdst' => true,
-        'dstlongname' => "Paraguay Summer Time",
-        'dstshortname' => 'PYST' ),
-    'America/Barbados' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Boa_Vista' => array(
-        'offset' => -14400000,
-        'longname' => "Amazon Standard Time",
-        'shortname' => 'AMT',
-        'hasdst' => false ),
-    'America/Caracas' => array(
-        'offset' => -14400000,
-        'longname' => "Venezuela Time",
-        'shortname' => 'VET',
-        'hasdst' => false ),
-    'America/Cuiaba' => array(
-        'offset' => -14400000,
-        'longname' => "Amazon Standard Time",
-        'shortname' => 'AMT',
-        'hasdst' => true,
-        'dstlongname' => "Amazon Summer Time",
-        'dstshortname' => 'AMST' ),
-    'America/Curacao' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Dominica' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Glace_Bay' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => true,
-        'dstlongname' => "Atlantic Daylight Time",
-        'dstshortname' => 'ADT' ),
-    'America/Goose_Bay' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => true,
-        'dstlongname' => "Atlantic Daylight Time",
-        'dstshortname' => 'ADT' ),
-    'America/Grenada' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Guadeloupe' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Guyana' => array(
-        'offset' => -14400000,
-        'longname' => "Guyana Time",
-        'shortname' => 'GYT',
-        'hasdst' => false ),
-    'America/Halifax' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => true,
-        'dstlongname' => "Atlantic Daylight Time",
-        'dstshortname' => 'ADT' ),
-    'America/La_Paz' => array(
-        'offset' => -14400000,
-        'longname' => "Bolivia Time",
-        'shortname' => 'BOT',
-        'hasdst' => false ),
-    'America/Manaus' => array(
-        'offset' => -14400000,
-        'longname' => "Amazon Standard Time",
-        'shortname' => 'AMT',
-        'hasdst' => false ),
-    'America/Martinique' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Montserrat' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Port_of_Spain' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Porto_Velho' => array(
-        'offset' => -14400000,
-        'longname' => "Amazon Standard Time",
-        'shortname' => 'AMT',
-        'hasdst' => false ),
-    'America/Puerto_Rico' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Santiago' => array(
-        'offset' => -14400000,
-        'longname' => "Chile Time",
-        'shortname' => 'CLT',
-        'hasdst' => true,
-        'dstlongname' => "Chile Summer Time",
-        'dstshortname' => 'CLST' ),
-    'America/Santo_Domingo' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/St_Kitts' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/St_Lucia' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/St_Thomas' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/St_Vincent' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Thule' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Tortola' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'America/Virgin' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'Antarctica/Palmer' => array(
-        'offset' => -14400000,
-        'longname' => "Chile Time",
-        'shortname' => 'CLT',
-        'hasdst' => true,
-        'dstlongname' => "Chile Summer Time",
-        'dstshortname' => 'CLST' ),
-    'Atlantic/Bermuda' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => true,
-        'dstlongname' => "Atlantic Daylight Time",
-        'dstshortname' => 'ADT' ),
-    'Atlantic/Stanley' => array(
-        'offset' => -14400000,
-        'longname' => "Falkland Is. Time",
-        'shortname' => 'FKT',
-        'hasdst' => true,
-        'dstlongname' => "Falkland Is. Summer Time",
-        'dstshortname' => 'FKST' ),
-    'Brazil/West' => array(
-        'offset' => -14400000,
-        'longname' => "Amazon Standard Time",
-        'shortname' => 'AMT',
-        'hasdst' => false ),
-    'Canada/Atlantic' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => true,
-        'dstlongname' => "Atlantic Daylight Time",
-        'dstshortname' => 'ADT' ),
-    'Chile/Continental' => array(
-        'offset' => -14400000,
-        'longname' => "Chile Time",
-        'shortname' => 'CLT',
-        'hasdst' => true,
-        'dstlongname' => "Chile Summer Time",
-        'dstshortname' => 'CLST' ),
-    'Etc/GMT+4' => array(
-        'offset' => -14400000,
-        'longname' => "GMT-04:00",
-        'shortname' => 'GMT-04:00',
-        'hasdst' => false ),
-    'PRT' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'SystemV/AST4' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => false ),
-    'SystemV/AST4ADT' => array(
-        'offset' => -14400000,
-        'longname' => "Atlantic Standard Time",
-        'shortname' => 'AST',
-        'hasdst' => true,
-        'dstlongname' => "Atlantic Daylight Time",
-        'dstshortname' => 'ADT' ),
-    'America/St_Johns' => array(
-        'offset' => -12600000,
-        'longname' => "Newfoundland Standard Time",
-        'shortname' => 'NST',
-        'hasdst' => true,
-        'dstlongname' => "Newfoundland Daylight Time",
-        'dstshortname' => 'NDT' ),
-    'CNT' => array(
-        'offset' => -12600000,
-        'longname' => "Newfoundland Standard Time",
-        'shortname' => 'NST',
-        'hasdst' => true,
-        'dstlongname' => "Newfoundland Daylight Time",
-        'dstshortname' => 'NDT' ),
-    'Canada/Newfoundland' => array(
-        'offset' => -12600000,
-        'longname' => "Newfoundland Standard Time",
-        'shortname' => 'NST',
-        'hasdst' => true,
-        'dstlongname' => "Newfoundland Daylight Time",
-        'dstshortname' => 'NDT' ),
-    'AGT' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Araguaina' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'America/Belem' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => false ),
-    'America/Buenos_Aires' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Catamarca' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Cayenne' => array(
-        'offset' => -10800000,
-        'longname' => "French Guiana Time",
-        'shortname' => 'GFT',
-        'hasdst' => false ),
-    'America/Cordoba' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Fortaleza' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'America/Godthab' => array(
-        'offset' => -10800000,
-        'longname' => "Western Greenland Time",
-        'shortname' => 'WGT',
-        'hasdst' => true,
-        'dstlongname' => "Western Greenland Summer Time",
-        'dstshortname' => 'WGST' ),
-    'America/Jujuy' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Maceio' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'America/Mendoza' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Miquelon' => array(
-        'offset' => -10800000,
-        'longname' => "Pierre & Miquelon Standard Time",
-        'shortname' => 'PMST',
-        'hasdst' => true,
-        'dstlongname' => "Pierre & Miquelon Daylight Time",
-        'dstshortname' => 'PMDT' ),
-    'America/Montevideo' => array(
-        'offset' => -10800000,
-        'longname' => "Uruguay Time",
-        'shortname' => 'UYT',
-        'hasdst' => false ),
-    'America/Paramaribo' => array(
-        'offset' => -10800000,
-        'longname' => "Suriname Time",
-        'shortname' => 'SRT',
-        'hasdst' => false ),
-    'America/Recife' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'America/Rosario' => array(
-        'offset' => -10800000,
-        'longname' => "Argentine Time",
-        'shortname' => 'ART',
-        'hasdst' => false ),
-    'America/Sao_Paulo' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'BET' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'Brazil/East' => array(
-        'offset' => -10800000,
-        'longname' => "Brazil Time",
-        'shortname' => 'BRT',
-        'hasdst' => true,
-        'dstlongname' => "Brazil Summer Time",
-        'dstshortname' => 'BRST' ),
-    'Etc/GMT+3' => array(
-        'offset' => -10800000,
-        'longname' => "GMT-03:00",
-        'shortname' => 'GMT-03:00',
-        'hasdst' => false ),
-    'America/Noronha' => array(
-        'offset' => -7200000,
-        'longname' => "Fernando de Noronha Time",
-        'shortname' => 'FNT',
-        'hasdst' => false ),
-    'Atlantic/South_Georgia' => array(
-        'offset' => -7200000,
-        'longname' => "South Georgia Standard Time",
-        'shortname' => 'GST',
-        'hasdst' => false ),
-    'Brazil/DeNoronha' => array(
-        'offset' => -7200000,
-        'longname' => "Fernando de Noronha Time",
-        'shortname' => 'FNT',
-        'hasdst' => false ),
-    'Etc/GMT+2' => array(
-        'offset' => -7200000,
-        'longname' => "GMT-02:00",
-        'shortname' => 'GMT-02:00',
-        'hasdst' => false ),
-    'America/Scoresbysund' => array(
-        'offset' => -3600000,
-        'longname' => "Eastern Greenland Time",
-        'shortname' => 'EGT',
-        'hasdst' => true,
-        'dstlongname' => "Eastern Greenland Summer Time",
-        'dstshortname' => 'EGST' ),
-    'Atlantic/Azores' => array(
-        'offset' => -3600000,
-        'longname' => "Azores Time",
-        'shortname' => 'AZOT',
-        'hasdst' => true,
-        'dstlongname' => "Azores Summer Time",
-        'dstshortname' => 'AZOST' ),
-    'Atlantic/Cape_Verde' => array(
-        'offset' => -3600000,
-        'longname' => "Cape Verde Time",
-        'shortname' => 'CVT',
-        'hasdst' => false ),
-    'Etc/GMT+1' => array(
-        'offset' => -3600000,
-        'longname' => "GMT-01:00",
-        'shortname' => 'GMT-01:00',
-        'hasdst' => false ),
-    'Africa/Abidjan' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Accra' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Bamako' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Banjul' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Bissau' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Casablanca' => array(
-        'offset' => 0,
-        'longname' => "Western European Time",
-        'shortname' => 'WET',
-        'hasdst' => false ),
-    'Africa/Conakry' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Dakar' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/El_Aaiun' => array(
-        'offset' => 0,
-        'longname' => "Western European Time",
-        'shortname' => 'WET',
-        'hasdst' => false ),
-    'Africa/Freetown' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Lome' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Monrovia' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Nouakchott' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Ouagadougou' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Sao_Tome' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Africa/Timbuktu' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'America/Danmarkshavn' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Atlantic/Canary' => array(
-        'offset' => 0,
-        'longname' => "Western European Time",
-        'shortname' => 'WET',
-        'hasdst' => true,
-        'dstlongname' => "Western European Summer Time",
-        'dstshortname' => 'WEST' ),
-    'Atlantic/Faeroe' => array(
-        'offset' => 0,
-        'longname' => "Western European Time",
-        'shortname' => 'WET',
-        'hasdst' => true,
-        'dstlongname' => "Western European Summer Time",
-        'dstshortname' => 'WEST' ),
-    'Atlantic/Madeira' => array(
-        'offset' => 0,
-        'longname' => "Western European Time",
-        'shortname' => 'WET',
-        'hasdst' => true,
-        'dstlongname' => "Western European Summer Time",
-        'dstshortname' => 'WEST' ),
-    'Atlantic/Reykjavik' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Atlantic/St_Helena' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Eire' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => true,
-        'dstlongname' => "Irish Summer Time",
-        'dstshortname' => 'IST' ),
-    'Etc/GMT' => array(
-        'offset' => 0,
-        'longname' => "GMT+00:00",
-        'shortname' => 'GMT+00:00',
-        'hasdst' => false ),
-    'Etc/GMT+0' => array(
-        'offset' => 0,
-        'longname' => "GMT+00:00",
-        'shortname' => 'GMT+00:00',
-        'hasdst' => false ),
-    'Etc/GMT-0' => array(
-        'offset' => 0,
-        'longname' => "GMT+00:00",
-        'shortname' => 'GMT+00:00',
-        'hasdst' => false ),
-    'Etc/GMT0' => array(
-        'offset' => 0,
-        'longname' => "GMT+00:00",
-        'shortname' => 'GMT+00:00',
-        'hasdst' => false ),
-    'Etc/Greenwich' => array(
-        'offset' => 0,
-        'longname' => "Greenwich Mean Time",
-        'shortname' => 'GMT',
-        'hasdst' => false ),
-    'Etc/UCT' => array(
-        'offset' => 0,
-        'longname' => "Coordinated Universal Time",
-        'shortname' => 'UTC',
-        'hasdst' => false ),
-    'Etc/UTC' => array(
-        'offset' => 0,
-        'longname' => "Coordinated Universal Time",
-        'shortname' => 'UTC',
-        'hasdst' => false ),
-    'Etc/Universal' => array(
-        'offset' => 0,
-        'longname' => "Coordinated Universal Time",
-        'shortname' => 'UTC',
-        'hasdst' => false ),
-    'Etc/Zulu' => array(
-        'offset' => 0,
-        'longname' => "Coordinated Universal Time",
-        'shortnam