# Date.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2006-2009 by Garmonbozia Research Group                 *
    00004  *   Anton E. Lebedevich, Konstantin V. Arkhipov                           *
    00005  *                                                                         *
    00006  *   This program is free software; you can redistribute it and/or modify  *
    00007  *   it under the terms of the GNU Lesser General Public License as        *
    00008  *   published by the Free Software Foundation; either version 3 of the    *
    00009  *   License, or (at your option) any later version.                       *
    00010  *                                                                         *
    00011  ***************************************************************************/
    00012 /* $Id$ */
    00013
    00021     class Date implements Stringable, DialectString
    00022     {
    00023         const WEEKDAY_MONDAY    = 1;
    00024         const WEEKDAY_TUESDAY   = 2;
    00025         const WEEKDAY_WEDNESDAY = 3;
    00026         const WEEKDAY_THURSDAY  = 4;
    00027         const WEEKDAY_FRIDAY    = 5;
    00028         const WEEKDAY_SATURDAY  = 6;
    00029         const WEEKDAY_SUNDAY    = 0; // because strftime('%w') is 0 on Sunday
    00030
    00031         protected $string   = null;
    00032         protected $int      = null;
    00033
    00034         protected $year     = null;
    00035         protected $month    = null;
    00036         protected $day      = null;
    00037
    00041         public static function create($date)
    00042         {
    00043             return new self($date);
    00044         }
    00045
    00046         public static function today($delimiter = '-')
    00047         {
    00048             return date("Y{$delimiter}m{$delimiter}d");
    00049         }
    00050
    00054         public static function makeToday()
    00055         {
    00056             return new self(self::today());
    00057         }
    00058
    00064         public static function makeFromWeek($weekNumber, $year = null)
    00065         {
    00066             if (!$year)
    00067                 $year = date('Y');
    00068
    00069             Assert::isTrue(
    00070                 ($weekNumber > 0)
    00071                 && ($weekNumber <= self::getWeekCountInYear($year))
    00072             );
    00073
    00074             $date =
    00075                 new self(
    00076                     date(
    00077                         self::getFormat(),
    00078                         mktime(
    00079                             0, 0, 0, 1, 1, $year
    00080                         )
    00081                     )
    00082                 );
    00083
    00084             $days =
    00085                 (
    00086                     (
    00087                         $weekNumber - 1
    00088                         + (self::getWeekCountInYear($year - 1) == 53 ? 1 : 0)
    00089                     )
    00090                     * 7
    00091                 ) + 1 - $date->getWeekDay();
    00092
    00093             return $date->modify("+{$days} day");
    00094         }
    00095
    00096         public static function dayDifference(Date $left, Date $right)
    00097         {
    00098             return
    00099                 gregoriantojd(
    00100                     $right->getMonth(),
    00101                     $right->getDay(),
    00102                     $right->getYear()
    00103                 )
    00104                 - gregoriantojd(
    00105                     $left->getMonth(),
    00106                     $left->getDay(),
    00107                     $left->getYear()
    00108                 );
    00109         }
    00110
    00111         public static function compare(Date $left, Date $right)
    00112         {
    00113             if ($left->int == $right->int)
    00114                 return 0;
    00115             else
    00116                 return ($left->int > $right->int ? 1 : -1);
    00117         }
    00118
    00119         public static function getWeekCountInYear($year)
    00120         {
    00121             return date('W', mktime(0, 0, 0, 12, 31, $year));
    00122         }
    00123
    00124         public function __construct($date)
    00125         {
    00126             if (is_int($date) || is_numeric($date)) { // unix timestamp
    00127                 $this->string = date($this->getFormat(), $date);
    00128             } elseif ($date && is_string($date))
    00129                 $this->stringImport($date);
    00130
    00131             if ($this->string === null) {
    00132                 throw new WrongArgumentException(
    00133                     "strange input given - '{$date}'"
    00134                 );
    00135             }
    00136
    00137             $this->import($this->string);
    00138             $this->buildInteger();
    00139         }
    00140
    00141         public function toStamp()
    00142         {
    00143             return $this->int;
    00144         }
    00145
    00146         public function toDate($delimiter = '-')
    00147         {
    00148             return
    00149                 $this->year
    00150                 .$delimiter
    00151                 .$this->month
    00152                 .$delimiter
    00153                 .$this->day;
    00154         }
    00155
    00156         public function getYear()
    00157         {
    00158             return $this->year;
    00159         }
    00160
    00161         public function getMonth()
    00162         {
    00163             return $this->month;
    00164         }
    00165
    00166         public function getDay()
    00167         {
    00168             return $this->day;
    00169         }
    00170
    00171         public function getWeek()
    00172         {
    00173             return date('W', $this->int);
    00174         }
    00175
    00176         public function getWeekDay()
    00177         {
    00178             return strftime('%w', $this->int);
    00179         }
    00180
    00184         public function spawn($modification = null)
    00185         {
    00186             $child = new $this($this->string);
    00187
    00188             if ($modification)
    00189                 return $child->modify($modification);
    00190
    00191             return $child;
    00192         }
    00193
    00198         public function modify($string)
    00199         {
    00200             try {
    00201                 $time = strtotime($string, $this->int);
    00202
    00203                 if ($time === false)
    00204                     throw new WrongArgumentException(
    00205                         "modification yielded false '{$string}'"
    00206                     );
    00207
    00208                 $this->int = $time;
    00209                 $this->string = date($this->getFormat(), $time);
    00210                 $this->import($this->string);
    00211             } catch (BaseException $e) {
    00212                 throw new WrongArgumentException(
    00213                     "wrong time string '{$string}'"
    00214                 );
    00215             }
    00216
    00217             return $this;
    00218         }
    00219
    00220         public function getDayStartStamp()
    00221         {
    00222             return
    00223                 mktime(
    00224                     0, 0, 0,
    00225                     $this->month,
    00226                     $this->day,
    00227                     $this->year
    00228                 );
    00229         }
    00230
    00231         public function getDayEndStamp()
    00232         {
    00233             return
    00234                 mktime(
    00235                     23, 59, 59,
    00236                     $this->month,
    00237                     $this->day,
    00238                     $this->year
    00239                 );
    00240         }
    00241
    00245         public function getFirstDayOfWeek($weekStart = Date::WEEKDAY_MONDAY)
    00246         {
    00247             return $this->spawn(
    00248                 '-'.((7 + $this->getWeekDay() - $weekStart) % 7).' days'
    00249             );
    00250         }
    00251
    00255         public function getLastDayOfWeek($weekStart = Date::WEEKDAY_MONDAY)
    00256         {
    00257             return $this->spawn(
    00258                 '+'.((13 - $this->getWeekDay() + $weekStart) % 7).' days'
    00259             );
    00260         }
    00261
    00262         public function toString()
    00263         {
    00264             return $this->string;
    00265         }
    00266
    00267         public function toDialectString(Dialect $dialect)
    00268         {
    00269             // there are no known differences yet
    00270             return $dialect->quoteValue($this->toString());
    00271         }
    00272
    00276         public function toIsoString()
    00277         {
    00278             return $this->toString();
    00279         }
    00280
    00284         public function toTimestamp()
    00285         {
    00286             return Timestamp::create($this->toStamp());
    00287         }
    00288
    00289         protected static function getFormat()
    00290         {
    00291             return 'Y-m-d';
    00292         }
    00293
    00294         /* void */ protected function import($string)
    00295         {
    00296             list($this->year, $this->month, $this->day) =
    00297                 explode('-', $string, 3);
    00298
    00299             if (!$this->month || !$this->day)
    00300                 throw new WrongArgumentException(
    00301                     'month and day must not be zero'
    00302                 );
    00303
    00304             $this->string =
    00305                 sprintf(
    00306                     '%04d-%02d-%02d',
    00307                     $this->year,
    00308                     $this->month,
    00309                     $this->day
    00310                 );
    00311
    00312             list($this->year, $this->month, $this->day) =
    00313                 explode('-', $this->string, 3);
    00314         }
    00315
    00316         /* void */ protected function stringImport($string)
    00317         {
    00318             $matches = array();
    00319
    00320             if (
    00321                 preg_match('/^(\d{1,4})-(\d{1,2})-(\d{1,2})$/', $string, $matches)
    00322             ) {
    00323                 if (checkdate($matches[2], $matches[3], $matches[1]))
    00324                     $this->string = $string;
    00325
    00326             } elseif (($stamp = strtotime($string)) !== false)
    00327                 $this->string = date($this->getFormat(), $stamp);
    00328         }
    00329
    00330         /* void */ protected function buildInteger()
    00331         {
    00332             $this->int =
    00333                 mktime(
    00334                     0, 0, 0,
    00335                     $this->month,
    00336                     $this->day,
    00337                     $this->year
    00338                 );
    00339         }
    00340     }
    00341 ?>