[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/datetime/src/ -> lmbDate.class.php (source)

   1  <?php
   2  /*

   3   * Limb PHP Framework

   4   *

   5   * @link http://limb-project.com

   6   * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)

   7   * @license    LGPL http://www.gnu.org/copyleft/lesser.html

   8   */
   9  lmb_require('limb/core/src/lmbObject.class.php');
  10  
  11  /**

  12   * class lmbDate.

  13   *

  14   * @package datetime

  15   * @version $Id: lmbDate.class.php 5969 2007-06-08 10:51:09Z pachanga $

  16   */
  17  class lmbDate extends lmbObject
  18  {
  19    //YYYY-MM-DD HH:MM:SS timezone

  20    const DATE_ISO_REGEX = '~^(([0-9]{4})-([0-9]{2})-([0-9]{2}))?((?(1)\s+)([0-9]{2}):([0-9]{2}):?([0-9]{2})?)?$~';
  21  
  22    /**

  23     * Defines what day starts the week.

  24     * Monday (1) is the international standard, Sunday (0) is used in US.

  25     * @see setWeekStartsAt()

  26     */
  27    static protected $week_starts_at = 1;
  28  
  29    protected $year = 0;
  30    protected $month = 0;
  31    protected $day = 0;
  32    protected $hour = 0;
  33    protected $minute = 0;
  34    protected $second = 0;
  35    protected $tz = '';
  36  
  37    function __construct($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
  38    {
  39      if(func_num_args() > 2)
  40      {
  41        $this->year   = (int)$year_or_date;
  42        $this->month  = (int)$month_or_tz;
  43        $this->day    = (int)$day;
  44        $this->hour   = (int)$hour;
  45        $this->minute = (int)$minute;
  46        $this->second = (int)$second;
  47        $this->tz     = $tz;
  48      }
  49      elseif(is_a($year_or_date, 'lmbDate'))
  50      {
  51        $this->_copy($year_or_date);
  52      }
  53      elseif(is_numeric($year_or_date))
  54      {
  55        $this->_setByStamp($year_or_date);
  56        $this->tz = $month_or_tz;
  57      }
  58      elseif(is_string($year_or_date))
  59      {
  60        $this->_setByString($year_or_date);
  61        $this->tz = $month_or_tz;
  62      }
  63      else
  64      {
  65        $this->_setByStamp(time());
  66        $this->tz = $month_or_tz;
  67      }
  68  
  69      if(!$this->isValid())
  70      {
  71        $args = func_get_args();
  72        throw new lmbException("Could not create date using args", $args);
  73      }
  74    }
  75  
  76    /**

  77     * Wrapper around constructor, it can be useful since the following is not allowed in PHP 'new lmbDate(..)->addDay(..)->'

  78     */
  79    static function create($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
  80    {
  81      if(func_num_args() > 2)
  82        return new lmbDate($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
  83      else
  84        return new lmbDate($year_or_date, $month_or_tz);
  85    }
  86  
  87    static function createByDays($days)
  88    {
  89      $days   -= 1721119;
  90      $century = floor((4 * $days - 1) / 146097);
  91      $days    = floor(4 * $days - 1 - 146097 * $century);
  92      $day     = floor($days / 4);
  93  
  94      $year    = floor((4 * $day +  3) / 1461);
  95      $day     = floor(4 * $day +  3 - 1461 * $year);
  96      $day     = floor(($day +  4) / 4);
  97  
  98      $month   = floor((5 * $day - 3) / 153);
  99      $day     = floor(5 * $day - 3 - 153 * $month);
 100      $day     = floor(($day +  5) /  5);
 101  
 102      if($month < 10)
 103      {
 104        $month +=3;
 105      }
 106      else
 107      {
 108        $month -=9;
 109        if($year++ == 99)
 110        {
 111          $year = 0;
 112          $century++;
 113        }
 114      }
 115  
 116      $century = sprintf('%02d', $century);
 117      $year    = sprintf('%02d', $year);
 118      return new lmbDate($century . $year, $month, $day);
 119    }
 120  
 121    static function setWeekStartsAt($n)
 122    {
 123      self :: $week_starts_at = $n;
 124    }
 125  
 126    static function getWeekStartsAt()
 127    {
 128      return self :: $week_starts_at;
 129    }
 130  
 131    static function stampToIso($stamp)
 132    {
 133      $date = new lmbDate((int)$stamp);
 134      return $date->getIsoDate();
 135    }
 136  
 137    function _createTimeZoneObject($code=null)
 138    {
 139      lmb_require('limb/datetime/src/lmbDateTimeZone.class.php');
 140  
 141      if(!$code)
 142        return lmbDateTimeZone::getDefault();
 143      else
 144        return new lmbDateTimeZone($code);
 145    }
 146  
 147    function isValid()
 148    {
 149      if($this->year < 0) return false;
 150      if($this->month < 0 || $this->month > 12) return false;
 151      if($this->day < 0 || $this->day > 31) return false;
 152      if($this->hour < 0 || $this->hour > 23) return false;
 153      if($this->minute < 0 || $this->minute > 59) return false;
 154      if($this->second < 0 || $this->second > 59) return false;
 155  
 156      //dirty hack for checkdate...

 157      return checkdate($this->month ? $this->month : 1,
 158                       $this->day ? $this->day : 1,
 159                       $this->year ? $this->year : 1);
 160    }
 161  
 162    static function validate($year_or_date=null, $month_or_tz=null, $day=null, $hour=0, $minute=0, $second=0, $tz='')
 163    {
 164      try
 165      {
 166        if(func_num_args() > 2)
 167          new lmbDate($year_or_date, $month_or_tz, $day, $hour, $minute, $second, $tz);
 168        else
 169          new lmbDate($year_or_date, $month_or_tz);
 170        return true;
 171      }
 172      catch(lmbException $e)
 173      {
 174        return false;
 175      }
 176    }
 177  
 178    protected function _setByString($string)
 179    {
 180      if(!preg_match(self :: DATE_ISO_REGEX, trim($string), $regs))
 181        throw new lmbException("Could not setup date using string '$string'");
 182  
 183      if(isset($regs[1]))
 184      {
 185        $this->year   = (int)$regs[2];
 186        $this->month  = (int)$regs[3];
 187        $this->day    = (int)$regs[4];
 188      }
 189  
 190      if(isset($regs[5]))
 191      {
 192        $this->hour   = (int)$regs[6];
 193        $this->minute = (int)$regs[7];
 194        if(isset($regs[8]))
 195          $this->second = (int)$regs[8];
 196      }
 197    }
 198  
 199    protected function _setByStamp($time)
 200    {
 201      if($time < 0 || !$arr = @getdate($time))
 202        throw new lmbException("Could not setup date using stamp'$time'");
 203  
 204      $this->year   = $arr['year'];
 205      $this->month  = $arr['mon'];
 206      $this->day    = $arr['mday'];
 207      $this->hour   = $arr['hours'];
 208      $this->minute = $arr['minutes'];
 209      $this->second = $arr['seconds'];
 210    }
 211  
 212    protected function _copy($date)
 213    {
 214      $this->year = $date->getYear();
 215      $this->month = $date->getMonth();
 216      $this->day = $date->getDay();
 217      $this->hour = $date->getHour();
 218      $this->minute = $date->getMinute();
 219      $this->second = $date->getSecond();
 220      $this->tz = $date->getTimeZone();
 221    }
 222  
 223    function getStamp()
 224    {
 225      //temporary ugly hack for unspecified year

 226      if(!$this->year)
 227        return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day);
 228      else
 229        return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
 230    }
 231  
 232    function date($format)
 233    {
 234      return date($format, $this->getStamp());
 235    }
 236  
 237    function strftime($format)
 238    {
 239      return strftime($format, $this->getStamp());
 240    }
 241  
 242    function getIsoDate($with_seconds = true)
 243    {
 244      return sprintf($with_seconds ? '%04d-%02d-%02d %02d:%02d:%02d' : '%04d-%02d-%02d %02d:%02d',
 245                     $this->getYear(), $this->getMonth(), $this->getDay(),
 246                     $this->getHour(), $this->getMinute(), $this->getSecond());
 247    }
 248  
 249    function getIsoShortDate()
 250    {
 251      return sprintf('%04d-%02d-%02d',
 252                     $this->getYear(), $this->getMonth(), $this->getDay());
 253    }
 254  
 255    function getIsoTime($with_seconds = true)
 256    {
 257      return sprintf($with_seconds ? '%02d:%02d:%02d' : '%02d:%02d',
 258                     $this->getHour(), $this->getMinute(), $this->getSecond());
 259    }
 260  
 261    function getIsoShortTime()
 262    {
 263      return $this->getIsoTime(false);
 264    }
 265  
 266    /**

 267     * @deprecated

 268     */
 269    function toTimestamp()
 270    {
 271      return $this->getStamp();
 272    }
 273  
 274    function toString()
 275    {
 276      return $this->getIsoDate();
 277    }
 278  
 279    function isInDaylightTime()
 280    {
 281      return $this->getTimeZoneObject()->inDaylightTime($this);
 282    }
 283  
 284    function toUTC()
 285    {
 286      $tz = $this->getTimeZoneObject();
 287  
 288      if($tz->getOffset($this) > 0)
 289        $date = $this->addSecond(-1 * intval($tz->getOffset($this) / 1000));
 290      else
 291        $date = $this->addSecond(intval(abs($tz->getOffset($this)) / 1000));
 292  
 293      return $date->setTimeZone('UTC');
 294    }
 295  
 296    /**

 297     * Compares object with $d date object.

 298     * return int 0 if the dates are equal, -1 if is before, 1 if is after than $d

 299     */
 300    function compare($d)
 301    {
 302      if(!$d instanceof lmbDate)
 303        throw new lmbException("Wrong date argument", array('arg' => $d));
 304  
 305      $s1 = $this->getStamp();
 306      $s2 = $d->getStamp();
 307  
 308      if($s1 > $s2)
 309        return 1;
 310      elseif($s2 > $s1)
 311        return -1;
 312      else
 313        return 0;
 314    }
 315  
 316    function isBefore($when, $use_time_zone=false)
 317    {
 318      if($this->compare($when, $use_time_zone) == -1)
 319        return true;
 320      else
 321        return false;
 322    }
 323  
 324    function isAfter($when, $use_time_zone=false)
 325    {
 326      if($this->compare($when, $use_time_zone) == 1)
 327        return true;
 328      else
 329        return false;
 330    }
 331  
 332    function isEqual($when, $use_time_zone=false)
 333    {
 334      if($this->compare($when, $use_time_zone) == 0)
 335        return true;
 336      else
 337        return false;
 338    }
 339  
 340    function isEqualDate($when)
 341    {
 342      return $this->stripTime()->isEqual($when->stripTime());
 343    }
 344  
 345    function isLeapYear()
 346    {
 347      return (($this->year % 4 == 0 &&  $this->year % 100 != 0) ||  $this->year % 400 == 0);
 348    }
 349  
 350    function getDayOfYear()
 351    {
 352      $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
 353  
 354      $julian = ($days[$this->month - 1] + $this->day);
 355  
 356      if($this->month > 2 &&  $this->isLeapYear())
 357        $julian++;
 358  
 359      return $julian;
 360    }
 361  
 362    function getDayOfWeek()
 363    {
 364      return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), self :: $week_starts_at);
 365    }
 366  
 367    function getIntlDayOfWeek()
 368    {
 369      return $this->_correctDayOfWeek($this->getPhpDayOfWeek(), 1);
 370    }
 371  
 372    function getPhpDayOfWeek()
 373    {
 374      $year = $this->year;
 375      $month = $this->month;
 376      $day = $this->day;
 377  
 378      if(1901 < $year && $year < 2038)
 379        return (int)date('w', mktime(0, 0, 0, $month, $day, $year));
 380  
 381      if($month > 2)
 382      {
 383        $month -= 2;
 384      }
 385      else
 386      {
 387        $month += 10;
 388        $year--;
 389      }
 390  
 391      $day = (floor((13 * $month - 1) / 5) +
 392              $day + ($year % 100) +
 393              floor(($year % 100) / 4) +
 394              floor(($year / 100) / 4) - 2 *
 395              floor($year / 100) + 77);
 396  
 397      return $day - 7 * floor($day / 7);
 398    }
 399  
 400    protected function _correctDayOfWeek($dow, $week_starts_at)
 401    {
 402      if($week_starts_at == 0)
 403        return $dow;
 404  
 405      if($dow == 0)
 406        return 6;
 407      return $dow - 1;
 408    }
 409  
 410    function getBeginOfDay()
 411    {
 412      return new lmbDate($this->year, $this->month, $this->day, $this->tz);
 413    }
 414  
 415    function getEndOfDay()
 416    {
 417      return new lmbDate($this->year, $this->month, $this->day, 23, 59, 59, $this->tz);
 418    }
 419  
 420    function getBeginOfWeek()
 421    {
 422      $this_weekday = $this->getPhpDayOfWeek();
 423      $interval = (7 - self :: $week_starts_at + $this_weekday) % 7;
 424      return lmbDate :: createByDays($this->getDateDays() - $interval);
 425    }
 426  
 427    function getEndOfWeek()
 428    {
 429      $this_weekday = $this->getPhpDayOfWeek();
 430      $interval = (6 + self :: $week_starts_at - $this_weekday) % 7;
 431      return lmbDate :: createByDays($this->getDateDays() + $interval);
 432    }
 433  
 434    function getBeginOfMonth()
 435    {
 436      return new lmbDate($this->year, $this->month, 1, $this->tz);
 437    }
 438  
 439    function getEndOfMonth()
 440    {
 441      return $this->setDay(1)->addMonth(1)->addDay(-1)->getEndOfDay();
 442    }
 443  
 444    function getBeginOfYear()
 445    {
 446      return new lmbDate($this->year, 1, 1, $this->tz);
 447    }
 448  
 449    function getEndOfYear()
 450    {
 451      return new lmbDate($this->year, 12, 31, 23, 59, 59, $this->tz);
 452    }
 453  
 454    function getWeekOfYear()
 455    {
 456      $day = $this->day;
 457      $month = $this->month;
 458      $year = $this->year;
 459  
 460