| [ Index ] |
PHP Cross Reference of Limb3 |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * Limb PHP Framework 4 * 5 * @link http://limb-project.com 6 * @copyright Copyright © 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