1<?php 2 /** 3 * Datetime class that contains common date/time functions 4 * @author Joseph Engo <jengo@phpgroupware.org> 5 * @author Mark Peters <skeeter@phpgroupware.org> 6 * @copyright Copyright (C) 2000,2001 Joseph Engo, Mark Peters 7 * @copyright Portions Copyright (C) 2000-2004 Free Software Foundation, Inc. http://www.fsf.org/ 8 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License 9 * @package phpgwapi 10 * @subpackage utilities 11 * @version $Id: class.phpgw_datetime.inc.php 18131 2007-04-25 13:44:07Z skwashd $ 12 */ 13 14 $d1 = strtolower(@substr(PHPGW_API_INC,0,3)); 15 $d2 = strtolower(@substr(PHPGW_SERVER_ROOT,0,3)); 16 $d3 = strtolower(@substr(PHPGW_APP_INC,0,3)); 17 if($d1 == 'htt' || $d1 == 'ftp' || $d2 == 'htt' || $d2 == 'ftp' || $d3 == 'htt' || $d3 == 'ftp') 18 { 19 echo 'Failed attempt to break in via an old Security Hole!<br />'."\n"; 20 exit; 21 } 22 unset($d1); 23 unset($d2); 24 unset($d3); 25 26 27 /** 28 * Datetime class that contains common date/time functions 29 * 30 * @package phpgwapi 31 * @subpackage utilities 32 */ 33 class phpgw_datetime 34 { 35 var $tz_offset; 36 var $days = Array(); 37 var $gmtnow = 0; 38 var $users_localtime; 39 var $cv_gmtdate; 40 41 function phpgw_datetime() 42 { 43 $this->tz_offset = 3600 * intval(@$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']); 44 print_debug('datetime::datetime::gmtnow',$this->gmtnow,'api'); 45 46 $error_occured = True; 47 // If we already have a GMT time, no need to do this again. 48 if(!$this->gmtnow) 49 { 50 if(isset($GLOBALS['phpgw_info']['server']['tz_offset'])) 51 { 52 $this->gmtnow = time() - (intval($GLOBALS['phpgw_info']['server']['tz_offset']) * 3600); 53 //echo "<p>set via tz_offset=".$GLOBALS['phpgw_info']['server']['tz_offset'].": gmtnow=".date('Y/m/d H:i',$this->gmtnow)."</p>\n"; 54 } 55 else 56 { 57 $this->gmtnow = time() - ($this->getbestguess() * 3600); 58 //echo "<p>set via bestguess=".$this->getbestguess().": gmtnow=".date('Y/m/d H:i',$this->gmtnow)."</p>\n"; 59 } 60 } 61 $this->users_localtime = time() + $this->tz_offset; 62 } 63 64 function getntpoffset() 65 { 66 $error_occured = False; 67 if(!@is_object($GLOBALS['phpgw']->network)) 68 { 69 $GLOBALS['phpgw']->network = createobject('phpgwapi.network'); 70 } 71 $server_time = time(); 72 73 if($GLOBALS['phpgw']->network->open_port('129.6.15.28',13,5)) 74 { 75 $line = $GLOBALS['phpgw']->network->bs_read_port(64); 76 $GLOBALS['phpgw']->network->close_port(); 77 78 $array = explode(' ',$line); 79 // host: 129.6.15.28 80 // Value returned is 52384 02-04-20 13:55:29 50 0 0 9.2 UTC(NIST) * 81 print_debug('Server datetime',time(),'api'); 82 print_debug('Temporary NTP datetime',$line,'api'); 83 if ($array[5] == 4) 84 { 85 $error_occured = True; 86 } 87 else 88 { 89 $date = explode('-',$array[1]); 90 $time = explode(':',$array[2]); 91 $this->gmtnow = mktime(intval($time[0]),intval($time[1]),intval($time[2]),intval($date[1]),intval($date[2]),intval($date[0]) + 2000); 92 print_debug('Temporary RFC epoch',$this->gmtnow,'api'); 93 print_debug('GMT',date('Ymd H:i:s',$this->gmtnow),'api'); 94 } 95 } 96 else 97 { 98 $error_occured = True; 99 } 100 101 if($error_occured == True) 102 { 103 return $this->getbestguess(); 104 } 105 else 106 { 107 return intval(($server_time - $this->gmtnow) / 3600); 108 } 109 } 110 111 function gethttpoffset() 112 { 113 $error_occured = False; 114 if(!@is_object($GLOBALS['phpgw']->network)) 115 { 116 $GLOBALS['phpgw']->network = createobject('phpgwapi.network'); 117 } 118 $server_time = time(); 119 120 $filename = 'http://132.163.4.213/timezone.cgi?GMT'; 121 $file = $GLOBALS['phpgw']->network->gethttpsocketfile($filename); 122 if(!$file) 123 { 124 return $this->getbestguess(); 125 } 126 $time = strip_tags($file[55]); 127 $date = strip_tags($file[56]); 128 129 print_debug('GMT DateTime',$date.' '.$time,'api'); 130 $dt_array = explode(' ',$date); 131 $temp_datetime = $dt_array[0].' '.substr($dt_array[2],0,-1).' '.substr($dt_array[1],0,3).' '.$dt_array[3].' '.$time.' GMT'; 132 print_debug('Reformulated GMT DateTime',$temp_datetime,'api'); 133 $this->gmtnow = $this->convert_rfc_to_epoch($temp_datetime); 134 print_debug('this->gmtnow',$this->gmtnow,'api'); 135 print_debug('server time',$server_time,'api'); 136 print_debug('server DateTime',date('D, d M Y H:i:s',$server_time),'api'); 137 return intval(($server_time - $this->gmtnow) / 3600); 138 } 139 140 function getbestguess() 141 { 142 print_debug('datetime::datetime::debug: Inside getting from local server','api'); 143 $server_time = time(); 144 // Calculate GMT time... 145 // If DST, add 1 hour... 146 // - (date('I') == 1?3600:0) 147 $this->gmtnow = $this->convert_rfc_to_epoch(gmdate('D, d M Y H:i:s',$server_time).' GMT'); 148 return intval(($server_time - $this->gmtnow) / 3600); 149 } 150 151 function convert_rfc_to_epoch($date_str) 152 { 153 $comma_pos = strpos($date_str,','); 154 if($comma_pos) 155 { 156 $date_str = substr($date_str,$comma_pos+1); 157 } 158 159 // This may need to be a reference to the different months in native tongue.... 160 $month= array( 161 'Jan' => 1, 162 'Feb' => 2, 163 'Mar' => 3, 164 'Apr' => 4, 165 'May' => 5, 166 'Jun' => 6, 167 'Jul' => 7, 168 'Aug' => 8, 169 'Sep' => 9, 170 'Oct' => 10, 171 'Nov' => 11, 172 'Dec' => 12 173 ); 174 $dta = array(); 175 $ta = array(); 176 177 // Convert "15 Jul 2000 20:50:22 +0200" to unixtime 178 $dta = explode(' ',$date_str); 179 $ta = explode(':',$dta[4]); 180 181 if(substr($dta[5],0,3) <> 'GMT') 182 { 183 $tzoffset = substr($dta[5],0,1); 184 $tzhours = intval(substr($dta[5],1,2)); 185 $tzmins = intval(substr($dta[5],3,2)); 186 switch ($tzoffset) 187 { 188 case '-': 189 (int)$ta[0] += $tzhours; 190 (int)$ta[1] += $tzmins; 191 break; 192 case '+': 193 (int)$ta[0] -= $tzhours; 194 (int)$ta[1] -= $tzmins; 195 break; 196 } 197 } 198 return mktime($ta[0],$ta[1],$ta[2],$month[$dta[2]],$dta[1],$dta[3]); 199 } 200 201 function get_weekday_start($year,$month,$day) 202 { 203 $weekday = $this->day_of_week($year,$month,$day); 204 switch($GLOBALS['phpgw_info']['user']['preferences']['calendar']['weekdaystarts']) 205 { 206 // Saturday is for arabic support 207 case 'Saturday': 208 $this->days = Array( 209 0 => 'Sat', 210 1 => 'Sun', 211 2 => 'Mon', 212 3 => 'Tue', 213 4 => 'Wed', 214 5 => 'Thu', 215 6 => 'Fri' 216 ); 217 switch($weekday) 218 { 219 case 6: 220 break; 221 case 0: 222 if ($day == 1) 223 { 224 if ($month == 1) 225 { 226 --$year; 227 $month = 12; 228 } 229 else 230 { 231 --$month; 232 } 233 $day = $this->days_in_month($month,$year); 234 } 235 else 236 { 237 --$day; 238 } 239 break; 240 default: 241 if ($day <= ($weekday + 1)) 242 { 243 if ($month == 1) 244 { 245 --$year; 246 $month = 12; 247 } 248 else 249 { 250 --$month; 251 } 252 $day = $this->days_in_month($month,$year) - $weekday; 253 } 254 else 255 { 256 $day -= ($weekday + 1); 257 } 258 } 259 break; 260 case 'Monday': 261 $this->days = Array( 262 0 => 'Mon', 263 1 => 'Tue', 264 2 => 'Wed', 265 3 => 'Thu', 266 4 => 'Fri', 267 5 => 'Sat', 268 6 => 'Sun' 269 ); 270 switch($weekday) 271 { 272 case 1: 273 break; 274 case 0: 275 if ($day <= 6) 276 { 277 if ($month == 1) 278 { 279 --$year; 280 $month = 12; 281 } 282 else 283 { 284 --$month; 285 } 286 $day = $this->days_in_month($month,$year) + ($day - 6); 287 } 288 else 289 { 290 $day -= 6; 291 } 292 break; 293 default: 294 if ($day <= ($weekday == 0) ? 6 : ($weekday-1)) 295 { 296 if ($month == 1) 297 { 298 --$year; 299 $month = 12; 300 } 301 else 302 { 303 --$month; 304 } 305 $day = $this->days_in_month($month,$year) + ($day - (($weekday == 0) ? 6 : ($weekday-1))); 306 } 307 else 308 { 309 $day -= ($weekday-1); 310 } 311 } 312 break; 313 case 'Sunday': 314 default: 315 $this->days = Array( 316 0 => 'Sun', 317 1 => 'Mon', 318 2 => 'Tue', 319 3 => 'Wed', 320 4 => 'Thu', 321 5 => 'Fri', 322 6 => 'Sat' 323 ); 324 if ($day <= $weekday) 325 { 326 if ($month == 1) 327 { 328 --$year; 329 $month = 12; 330 } 331 else 332 { 333 --$month; 334 } 335 $day = $this->days_in_month($month,$year) + ($day - $weekday); 336 } 337 else 338 { 339 $day -= $weekday; 340 } 341 } 342 $sday = mktime(2,0,0,$month,$day,$year); 343 return $sday - 7200; 344 } 345 346 function is_leap_year($year) 347 { 348 if ((intval($year) % 4 == 0) && (intval($year) % 100 != 0) || (intval($year) % 400 == 0)) 349 { 350 return 1; 351 } 352 else 353 { 354 return 0; 355 } 356 } 357 358 function days_in_month($month,$year) 359 { 360 $days = Array( 361 1 => 31, 362 2 => 28 + $this->is_leap_year(intval($year)), 363 3 => 31, 364 4 => 30, 365 5 => 31, 366 6 => 30, 367 7 => 31, 368 8 => 31, 369 9 => 30, 370 10 => 31, 371 11 => 30, 372 12 => 31 373 ); 374 return $days[intval($month)]; 375 } 376 377 function date_valid($year,$month,$day) 378 { 379 return checkdate(intval($month),intval($day),intval($year)); 380 } 381 382 function time_valid($hour,$minutes,$seconds) 383 { 384 if(intval($hour) < 0 || intval($hour) > 24) 385 { 386 return False; 387 } 388 if(intval($minutes) < 0 || intval($minutes) > 59) 389 { 390 return False; 391 } 392 if(intval($seconds) < 0 || intval($seconds) > 59) 393 { 394 return False; 395 } 396 397 return True; 398 } 399 400 function day_of_week($year,$month,$day) 401 { 402 if($month > 2) 403 { 404 $month -= 2; 405 } 406 else 407 { 408 $month += 10; 409 $year--; 410 } 411 $day = (floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4) + floor(($year / 100) / 4) - 2 * floor($year / 100) + 77); 412 return (($day - 7 * floor($day / 7))); 413 } 414 415 function day_of_year($year,$month,$day) 416 { 417 $days = array(0,31,59,90,120,151,181,212,243,273,304,334); 418 419 $julian = ($days[$month - 1] + $day); 420 421 if($month > 2 && $this->is_leap_year($year)) 422 { 423 $julian++; 424 } 425 return($julian); 426 } 427 428 /** 429 * Get the number of days between two dates 430 * 431 * @author Steven Cramer/Ralf Becker 432 * @param $m1 - Month of first date 433 * @param $d1 - Day of first date 434 * @param $y1 - Year of first date 435 * @param $m2 - Month of second date 436 * @param $d2 - Day of second date 437 * @param $y2 - Year of second date 438 * @return integer Date 2 minus Date 1 in days 439 * @internal the last param == 0, ensures that the calculation is always done without daylight-saveing 440 */ 441 function days_between($m1,$d1,$y1,$m2,$d2,$y2) 442 { 443 return intval((mktime(0,0,0,$m2,$d2,$y2,0) - mktime(0,0,0,$m1,$d1,$y1,0)) / 86400); 444 } 445 446 function date_compare($a_year,$a_month,$a_day,$b_year,$b_month,$b_day) 447 { 448 $a_date = mktime(0,0,0,intval($a_month),intval($a_day),intval($a_year)); 449 $b_date = mktime(0,0,0,intval($b_month),intval($b_day),intval($b_year)); 450 if($a_date == $b_date) 451 { 452 return 0; 453 } 454 elseif($a_date > $b_date) 455 { 456 return 1; 457 } 458 elseif($a_date < $b_date) 459 { 460 return -1; 461 } 462 } 463 464 function time_compare($a_hour,$a_minute,$a_second,$b_hour,$b_minute,$b_second) 465 { 466 // I use the 1970/1/2 to compare the times, as the 1. can get via TZ-offest still 467 // before 1970/1/1, which is the earliest date allowed on windows 468 $a_time = mktime(intval($a_hour),intval($a_minute),intval($a_second),1,2,1970); 469 $b_time = mktime(intval($b_hour),intval($b_minute),intval($b_second),1,2,1970); 470 if($a_time == $b_time) 471 { 472 return 0; 473 } 474 elseif($a_time > $b_time) 475 { 476 return 1; 477 } 478 elseif($a_time < $b_time) 479 { 480 return -1; 481 } 482 } 483 484 function makegmttime($hour,$minute,$second,$month,$day,$year) 485 { 486 return $this->gmtdate(mktime($hour, $minute, $second, $month, $day, $year)); 487 } 488 489 function localdates($localtime) 490 { 491 $date = Array('raw','day','month','year','full','dow','dm','bd'); 492 $date['raw'] = $localtime; 493 $date['year'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'Y')); 494 $date['month'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'m')); 495 $date['day'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'d')); 496 $date['full'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'Ymd')); 497 $date['bd'] = mktime(0,0,0,$date['month'],$date['day'],$date['year']); 498 $date['dm'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'dm')); 499 $date['dow'] = $this->day_of_week($date['year'],$date['month'],$date['day']); 500 $date['hour'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'H')); 501 $date['minute'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'i')); 502 $date['second'] = intval($GLOBALS['phpgw']->common->show_date($date['raw'],'s')); 503 504 return $date; 505 } 506 507 function gmtdate($localtime) 508 { 509 return $this->localdates($localtime - $this->tz_offset); 510 } 511 512 /** 513 * Convert a date from one format to another 514 * 515 * @param string $date Date in source format representation 516 * @param string $formatSource Format of the passed date 517 * @param string $formatTarget Target date format 518 * @return string Date in target format representation 519 */ 520 function convertDate($date, $formatSource, $formatTarget) 521 { 522 // get format separator character 523 $formatSourceSepChar = substr($formatSource,1,1); 524 $formatSourceArray = explode($formatSourceSepChar, $formatSource); 525 $dateSourceArray = explode($formatSourceSepChar, $date); 526 527 $keyNum = count($formatSourceArray); 528 $valNum = count($dateSourceArray); 529 if($keyNum != $valNum) 530 { 531 return false; 532 } 533 534 $map_date = array(); 535 for($i=0; $i<$keyNum; $i++) 536 { 537 $key = $formatSourceArray[$i]; 538 $val = $dateSourceArray[$i]; 539 540 if($key == 'M') 541 { 542 for($j=1; $j <=12; $j++) 543 { 544 if(date('M',mktime(0,0,0,$j,1,2000)) == $val) 545 { 546 $map_date['m'] = $j; 547 } 548 } 549 } 550 else 551 { 552 $map_date[strtolower($key)] = intval($val); 553 } 554 } 555 return date($formatTarget, mktime(0,0,0,$map_date['m'], $map_date['d'], $map_date['y'])); 556 } 557 558 } 559?> 560