[ Index ]

PHP Cross Reference of MyBB 1.8.38

title

Body

[close]

/inc/ -> functions_time.php (source)

   1  <?php
   2  /** This file is distributed with MyBB under the BSD License package and modified to work with MyBB **/
   3  
   4  /**
   5  ADOdb Date Library, part of the ADOdb abstraction library
   6  Download: http://phplens.com/phpeverywhere/
   7  
   8  PHP native date functions use integer timestamps for computations.
   9  Because of this, dates are restricted to the years 1901-2038 on Unix
  10  and 1970-2038 on Windows due to integer overflow for dates beyond
  11  those years. This library overcomes these limitations by replacing the
  12  native function's signed integers (normally 32-bits) with PHP floating
  13  point numbers (normally 64-bits).
  14  
  15  Dates from 100 A.D. to 3000 A.D. and later
  16  have been tested. The minimum is 100 A.D. as <100 will invoke the
  17  2 => 4 digit year conversion. The maximum is billions of years in the
  18  future, but this is a theoretical limit as the computation of that year
  19  would take too long with the current implementation of adodb_mktime().
  20  
  21  This library replaces native functions as follows:
  22  
  23  <pre>
  24      getdate()  with  adodb_getdate()
  25      date()     with  adodb_date()
  26      gmdate()   with  adodb_gmdate()
  27      mktime()   with  adodb_mktime()
  28      gmmktime() with  adodb_gmmktime()
  29      strftime() with  adodb_strftime()
  30      strftime() with  adodb_gmstrftime()
  31  </pre>
  32  
  33  The parameters are identical, except that adodb_date() accepts a subset
  34  of date()'s field formats. Mktime() will convert from local time to GMT,
  35  and date() will convert from GMT to local time, but daylight savings is
  36  not handled currently.
  37  
  38  This library is independant of the rest of ADOdb, and can be used
  39  as standalone code.
  40  
  41  PERFORMANCE
  42  
  43  For high speed, this library uses the native date functions where
  44  possible, and only switches to PHP code when the dates fall outside
  45  the 32-bit signed integer range.
  46  
  47  GREGORIAN CORRECTION
  48  
  49  Pope Gregory shortened October of A.D. 1582 by ten days. Thursday,
  50  October 4, 1582 (Julian) was followed immediately by Friday, October 15,
  51  1582 (Gregorian).
  52  
  53  Since 0.06, we handle this correctly, so:
  54  
  55  adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
  56      == 24 * 3600 (1 day)
  57  
  58  =============================================================================
  59  
  60  COPYRIGHT
  61  
  62  (c) 2003-2005 John Lim and released under BSD-style license except for code by
  63  jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
  64  and originally found at http://www.php.net/manual/en/function.mktime.php
  65  
  66  =============================================================================
  67  
  68  BUG REPORTS
  69  
  70  These should be posted to the ADOdb forums at
  71  
  72      http://phplens.com/lens/lensforum/topics.php?id=4
  73  
  74  =============================================================================
  75  */
  76  
  77  
  78  /* Initialization */
  79  
  80  /*
  81      Version Number
  82  */
  83  define('ADODB_DATE_VERSION', 0.33);
  84  
  85  $ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
  86  
  87  /*
  88      This code was originally for windows. But apparently this problem happens
  89      also with Linux, RH 7.3 and later!
  90  
  91      glibc-2.2.5-34 and greater has been changed to return -1 for dates <
  92      1970.  This used to work.  The problem exists with RedHat 7.3 and 8.0
  93      echo (mktime(0, 0, 0, 1, 1, 1960));  // prints -1
  94  
  95      References:
  96       http://bugs.php.net/bug.php?id=20048&edit=2
  97       http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html
  98  */
  99  
 100  if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
 101  
 102  /**
 103      Returns day of week, 0 = Sunday,... 6=Saturday.
 104      Algorithm from PEAR::Date_Calc
 105  */
 106  function adodb_dow($year, $month, $day)
 107  {
 108  /*
 109  Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
 110  proclaimed that from that time onwards 3 days would be dropped from the calendar
 111  every 400 years.
 112  
 113  Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
 114  */
 115      if ($year <= 1582) {
 116          if ($year < 1582 ||
 117              ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
 118           else
 119              $greg_correction = 0;
 120      } else
 121          $greg_correction = 0;
 122  
 123      if($month > 2)
 124          $month -= 2;
 125      else {
 126          $month += 10;
 127          $year--;
 128      }
 129  
 130      $day =  floor((13 * $month - 1) / 5) +
 131              $day + ($year % 100) +
 132              floor(($year % 100) / 4) +
 133              floor(($year / 100) / 4) - 2 *
 134              floor($year / 100) + 77 + $greg_correction;
 135  
 136      return $day - 7 * floor($day / 7);
 137  }
 138  
 139  /**
 140   Checks for leap year, returns true if it is. No 2-digit year check. Also
 141   handles julian calendar correctly.
 142  */
 143  function _adodb_is_leap_year($year)
 144  {
 145      if ($year % 4 != 0) return false;
 146  
 147      if ($year % 400 == 0) {
 148          return true;
 149      // if gregorian calendar (>1582), century not-divisible by 400 is not leap
 150      } else if ($year > 1582 && $year % 100 == 0 ) {
 151          return false;
 152      }
 153  
 154      return true;
 155  }
 156  
 157  /**
 158   checks for leap year, returns true if it is. Has 2-digit year check
 159  */
 160  function adodb_is_leap_year($year)
 161  {
 162      return  _adodb_is_leap_year(adodb_year_digit_check($year));
 163  }
 164  
 165  /**
 166      Fix 2-digit years. Works for any century.
 167       Assumes that if 2-digit is more than 30 years in future, then previous century.
 168  */
 169  function adodb_year_digit_check($y)
 170  {
 171      if ($y < 100) {
 172  
 173          $yr = (integer) date("Y");
 174          $century = (integer) ($yr /100);
 175  
 176          if ($yr%100 > 50) {
 177              $c1 = $century + 1;
 178              $c0 = $century;
 179          } else {
 180              $c1 = $century;
 181              $c0 = $century - 1;
 182          }
 183          $c1 *= 100;
 184          // if 2-digit year is less than 30 years in future, set it to this century
 185          // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
 186          if (($y + $c1) < $yr+30) $y = $y + $c1;
 187          else $y = $y + $c0*100;
 188      }
 189      return $y;
 190  }
 191  
 192  function adodb_get_gmt_diff_ts($ts)
 193  {
 194      if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) {
 195          $arr = getdate($ts);
 196          $y = $arr['year'];
 197          $m = $arr['mon'];
 198          $d = $arr['mday'];
 199          return adodb_get_gmt_diff($y,$m,$d);
 200      } else {
 201          return adodb_get_gmt_diff(false,false,false);
 202      }
 203  
 204  }
 205  
 206  /**
 207   get local time zone offset from GMT. Does not handle historical timezones before 1970.
 208  */
 209  function adodb_get_gmt_diff($y,$m,$d)
 210  {
 211  static $TZ,$tzo;
 212  global $ADODB_DATETIME_CLASS;
 213  
 214      if (!defined('ADODB_TEST_DATES')) $y = false;
 215      else if ($y < 1970 || $y >= 2038) $y = false;
 216  
 217      if ($ADODB_DATETIME_CLASS && $y !== false) {
 218          $dt = new DateTime();
 219          $dt->setISODate($y,$m,$d);
 220          if (empty($tzo)) {
 221              $tzo = new DateTimeZone(date_default_timezone_get());
 222          #    $tzt = timezone_transitions_get( $tzo );
 223          }
 224          return -$tzo->getOffset($dt);
 225      } else {
 226          if (isset($TZ)) return $TZ;
 227          $y = date('Y');
 228          $TZ = mktime(0,0,0,12,2,$y) - gmmktime(0,0,0,12,2,$y);
 229      }
 230  
 231      return $TZ;
 232  }
 233  
 234  /**
 235      Returns an array with date info.
 236  */
 237  function adodb_getdate($d=false,$fast=false)
 238  {
 239      if ($d === false) return getdate();
 240      if (!defined('ADODB_TEST_DATES')) {
 241          if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 242              if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
 243                  return @getdate($d);
 244          }
 245      }
 246      return _adodb_getdate($d);
 247  }
 248  
 249  $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
 250  $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
 251  
 252  /**
 253      Low-level function that returns the getdate() array. We have a special
 254      $fast flag, which if set to true, will return fewer array values,
 255      and is much faster as it does not calculate dow, etc.
 256  */
 257  function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
 258  {
 259  static $YRS;
 260  global $_month_table_normal,$_month_table_leaf;
 261  
 262      $d =  $origd - ($is_gmt ? 0 : adodb_get_gmt_diff_ts($origd));
 263      $_day_power = 86400;
 264      $_hour_power = 3600;
 265      $_min_power = 60;
 266  
 267      if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction
 268  
 269      $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
 270      $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
 271  
 272      $d366 = $_day_power * 366;
 273      $d365 = $_day_power * 365;
 274  
 275      if ($d < 0) {
 276  
 277          if (empty($YRS)) $YRS = array(
 278              1970 => 0,
 279              1960 => -315619200,
 280              1950 => -631152000,
 281              1940 => -946771200,
 282              1930 => -1262304000,
 283              1920 => -1577923200,
 284              1910 => -1893456000,
 285              1900 => -2208988800,
 286              1890 => -2524521600,
 287              1880 => -2840140800,
 288              1870 => -3155673600,
 289              1860 => -3471292800,
 290              1850 => -3786825600,
 291              1840 => -4102444800,
 292              1830 => -4417977600,
 293              1820 => -4733596800,
 294              1810 => -5049129600,
 295              1800 => -5364662400,
 296              1790 => -5680195200,
 297              1780 => -5995814400,
 298              1770 => -6311347200,
 299              1760 => -6626966400,
 300              1750 => -6942499200,
 301              1740 => -7258118400,
 302              1730 => -7573651200,
 303              1720 => -7889270400,
 304              1710 => -8204803200,
 305              1700 => -8520336000,
 306              1690 => -8835868800,
 307              1680 => -9151488000,
 308              1670 => -9467020800,
 309              1660 => -9782640000,
 310              1650 => -10098172800,
 311              1640 => -10413792000,
 312              1630 => -10729324800,
 313              1620 => -11044944000,
 314              1610 => -11360476800,
 315              1600 => -11676096000);
 316  
 317          if ($is_gmt) $origd = $d;
 318          // The valid range of a 32bit signed timestamp is typically from
 319          // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
 320          //
 321  
 322          # old algorithm iterates through all years. new algorithm does it in
 323          # 10 year blocks
 324  
 325          /*
 326          # old algo
 327          for ($a = 1970 ; --$a >= 0;) {
 328              $lastd = $d;
 329  
 330              if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
 331              else $d += $d365;
 332  
 333              if ($d >= 0) {
 334                  $year = $a;
 335                  break;
 336              }
 337          }
 338          */
 339  
 340          $lastsecs = 0;
 341          $lastyear = 1970;
 342          foreach($YRS as $year => $secs) {
 343              if ($d >= $secs) {
 344                  $a = $lastyear;
 345                  break;
 346              }
 347              $lastsecs = $secs;
 348              $lastyear = $year;
 349          }
 350  
 351          $d -= $lastsecs;
 352          if (!isset($a)) $a = $lastyear;
 353  
 354          //echo ' yr=',$a,' ', $d,'.';
 355  
 356          for (; --$a >= 0;) {
 357              $lastd = $d;
 358  
 359              if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
 360              else $d += $d365;
 361  
 362              if ($d >= 0) {
 363                  $year = $a;
 364                  break;
 365              }
 366          }
 367          /**/
 368  
 369          $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
 370  
 371          $d = $lastd;
 372          $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
 373          for ($a = 13 ; --$a > 0;) {
 374              $lastd = $d;
 375              $d += $mtab[$a] * $_day_power;
 376              if ($d >= 0) {
 377                  $month = $a;
 378                  $ndays = $mtab[$a];
 379                  break;
 380              }
 381          }
 382  
 383          $d = $lastd;
 384          $day = $ndays + ceil(($d+1) / ($_day_power));
 385  
 386          $d += ($ndays - $day+1)* $_day_power;
 387          $hour = floor($d/$_hour_power);
 388  
 389      } else {
 390          for ($a = 1970 ;; $a++) {
 391              $lastd = $d;
 392  
 393              if ($leaf = _adodb_is_leap_year($a)) $d -= $d366;
 394              else $d -= $d365;
 395              if ($d < 0) {
 396                  $year = $a;
 397                  break;
 398              }
 399          }
 400          $secsInYear = $lastd;
 401          $d = $lastd;
 402          $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
 403          for ($a = 1 ; $a <= 12; $a++) {
 404              $lastd = $d;
 405              $d -= $mtab[$a] * $_day_power;
 406              if ($d < 0) {
 407                  $month = $a;
 408                  $ndays = $mtab[$a];
 409                  break;
 410              }
 411          }
 412          $d = $lastd;
 413          $day = ceil(($d+1) / $_day_power);
 414          $d = $d - ($day-1) * $_day_power;
 415          $hour = floor($d /$_hour_power);
 416      }
 417  
 418      $d -= $hour * $_hour_power;
 419      $min = floor($d/$_min_power);
 420      $secs = $d - $min * $_min_power;
 421      if ($fast) {
 422          return array(
 423          'seconds' => $secs,
 424          'minutes' => $min,
 425          'hours' => $hour,
 426          'mday' => $day,
 427          'mon' => $month,
 428          'year' => $year,
 429          'yday' => floor($secsInYear/$_day_power),
 430          'leap' => $leaf,
 431          'ndays' => $ndays
 432          );
 433      }
 434  
 435      $dow = adodb_dow($year,$month,$day);
 436  
 437      return array(
 438          'seconds' => $secs,
 439          'minutes' => $min,
 440          'hours' => $hour,
 441          'mday' => $day,
 442          'wday' => $dow,
 443          'mon' => $month,
 444          'year' => $year,
 445          'yday' => floor($secsInYear/$_day_power),
 446          'weekday' => gmdate('l',$_day_power*(3+$dow)),
 447          'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
 448          0 => $origd
 449      );
 450  }
 451  
 452  function adodb_tz_offset($gmt,$isphp5)
 453  {
 454      $zhrs = abs($gmt)/3600;
 455      $hrs = floor($zhrs);
 456      if ($isphp5)
 457          return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
 458      else
 459          return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
 460  }
 461  
 462  function adodb_gmdate($fmt,$d=false)
 463  {
 464      return adodb_date($fmt,$d,true);
 465  }
 466  
 467  // accepts unix timestamp and iso date format in $d
 468  function adodb_date2($fmt, $d=false, $is_gmt=false)
 469  {
 470      if ($d !== false) {
 471          if (!preg_match(
 472              "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
 473              ($d), $rr)) return adodb_date($fmt,false,$is_gmt);
 474  
 475          if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
 476  
 477          // h-m-s-MM-DD-YY
 478          if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt);
 479          else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt);
 480      }
 481  
 482      return adodb_date($fmt,$d,$is_gmt);
 483  }
 484  
 485  /**
 486      Return formatted date based on timestamp $d
 487  */
 488  function adodb_date($fmt,$d=false,$is_gmt=false)
 489  {
 490  static $daylight;
 491  global $ADODB_DATETIME_CLASS;
 492  
 493      if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
 494      if (!defined('ADODB_TEST_DATES')) {
 495          if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 496              if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
 497                  return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
 498  
 499          }
 500      }
 501      $_day_power = 86400;
 502  
 503      $arr = _adodb_getdate($d,true,$is_gmt);
 504  
 505      if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
 506      if ($daylight) adodb_daylight_sv($arr, $is_gmt);
 507  
 508      $year = $arr['year'];
 509      $month = $arr['mon'];
 510      $day = $arr['mday'];
 511      $hour = $arr['hours'];
 512      $min = $arr['minutes'];
 513      $secs = $arr['seconds'];
 514  
 515      $max = strlen($fmt);
 516      $dates = '';
 517  
 518      $isphp5 = PHP_VERSION >= 5;
 519  
 520      /*
 521          at this point, we have the following integer vars to manipulate:
 522          $year, $month, $day, $hour, $min, $secs
 523      */
 524      for ($i=0; $i < $max; $i++) {
 525          switch($fmt[$i]) {
 526          case 'T':
 527              if ($ADODB_DATETIME_CLASS) {
 528                  $dt = new DateTime();
 529                  $dt->SetDate($year,$month,$day);
 530                  $dates .= $dt->Format('T');
 531              } else
 532                  $dates .= date('T');
 533              break;
 534          // YEAR
 535          case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
 536          case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
 537  
 538              // 4.3.11 uses '04 Jun 2004'
 539              // 4.3.8 uses  ' 4 Jun 2004'
 540              $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '
 541                  . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
 542  
 543              if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour;
 544  
 545              if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
 546  
 547              if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
 548  
 549              $gmt = adodb_get_gmt_diff($year,$month,$day);
 550  
 551              $dates .= ' '.adodb_tz_offset($gmt,$isphp5);
 552              break;
 553  
 554          case 'Y': $dates .= $year; break;
 555          case 'y': $dates .= substr($year,strlen($year)-2,2); break;
 556          // MONTH
 557          case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
 558          case 'Q': $dates .= ($month+3)>>2; break;
 559          case 'n': $dates .= $month; break;
 560          case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
 561          case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
 562          // DAY
 563          case 't': $dates .= $arr['ndays']; break;
 564          case 'z': $dates .= $arr['yday']; break;
 565          case 'w': $dates .= adodb_dow($year,$month,$day); break;
 566          case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
 567          case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
 568          case 'j': $dates .= $day; break;
 569          case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
 570          case 'S':
 571              $d10 = $day % 10;
 572              if ($d10 == 1) $dates .= 'st';
 573              else if ($d10 == 2 && $day != 12) $dates .= 'nd';
 574              else if ($d10 == 3) $dates .= 'rd';
 575              else $dates .= 'th';
 576              break;
 577  
 578          // HOUR
 579          case 'Z':
 580              $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff($year,$month,$day); break;
 581          case 'O':
 582              $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day);
 583  
 584              $dates .= adodb_tz_offset($gmt,$isphp5);
 585              break;
 586  
 587          case 'H':
 588              if ($hour < 10) $dates .= '0'.$hour;
 589              else $dates .= $hour;
 590              break;
 591          case 'h':
 592              if ($hour > 12) $hh = $hour - 12;
 593              else {
 594                  if ($hour == 0) $hh = '12';
 595                  else $hh = $hour;
 596              }
 597  
 598              if ($hh < 10) $dates .= '0'.$hh;
 599              else $dates .= $hh;
 600              break;
 601  
 602          case 'G':
 603              $dates .= $hour;
 604              break;
 605  
 606          case 'g':
 607              if ($hour > 12) $hh = $hour - 12;
 608              else {
 609                  if ($hour == 0) $hh = '12';
 610                  else $hh = $hour;
 611              }
 612              $dates .= $hh;
 613              break;
 614          // MINUTES
 615          case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
 616          // SECONDS
 617          case 'U': $dates .= $d; break;
 618          case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
 619          // AM/PM
 620          // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
 621          case 'a':
 622              if ($hour>=12) $dates .= 'pm';
 623              else $dates .= 'am';
 624              break;
 625          case 'A':
 626              if ($hour>=12) $dates .= 'PM';
 627              else $dates .= 'AM';
 628              break;
 629          default:
 630              $dates .= $fmt[$i]; break;
 631          // ESCAPE
 632          case "\\":
 633              $i++;
 634              if ($i < $max) $dates .= $fmt[$i];
 635              break;
 636          }
 637      }
 638      return $dates;
 639  }
 640  
 641  /**
 642      Returns a timestamp given a GMT/UTC time.
 643      Note that $is_dst is not implemented and is ignored.
 644  */
 645  function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
 646  {
 647      return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
 648  }
 649  
 650  /**
 651      Return a timestamp given a local time. Originally by jackbbs.
 652      Note that $is_dst is not implemented and is ignored.
 653  
 654      Not a very fast algorithm - O(n) operation. Could be optimized to O(1).
 655  
 656      NOTE: returns time() when the year is > 9999
 657  */
 658  function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false)
 659  {
 660      if (!defined('ADODB_TEST_DATES')) {
 661  
 662          if ($mon === false) {
 663              return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
 664          }
 665  
 666          // for windows, we don't check 1970 because with timezone differences,
 667          // 1 Jan 1970 could generate negative timestamp, which is illegal
 668          $usephpfns = (1971 < $year && $year < 2038
 669              || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
 670              );
 671  
 672  
 673          if ($usephpfns && ($year + $mon/12+$day/365.25+$hr/(24*365.25) >= 2038)) $usephpfns = false;
 674  
 675          if ($usephpfns) {
 676                  return $is_gmt ?
 677                      @gmmktime($hr,$min,$sec,$mon,$day,$year):
 678                      @mktime($hr,$min,$sec,$mon,$day,$year);
 679          }
 680      }
 681  
 682      $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$mon,$day);
 683  
 684      /*
 685      # disabled because some people place large values in $sec.
 686      # however we need it for $mon because we use an array...
 687      $hr = (int)$hr;
 688      $min = (int)$min;
 689      $sec = (int)$sec;
 690      */
 691      $mon = (int)$mon;
 692      $day = (int)$day;
 693      $year = (int)$year;
 694  
 695  
 696      $year = adodb_year_digit_check($year);
 697  
 698      if ($mon > 12) {
 699          $y = floor(($mon-1)/ 12);
 700          $year += $y;
 701          $mon -= $y*12;
 702      } else if ($mon < 1) {
 703          $y = ceil((1-$mon) / 12);
 704          $year -= $y;
 705          $mon += $y*12;
 706      }
 707  
 708      $_day_power = 86400;
 709      $_hour_power = 3600;
 710      $_min_power = 60;
 711  
 712      $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
 713      $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
 714  
 715      $_total_date = 0;
 716      if($year > 9999) {
 717          return time();
 718      } else if ($year >= 1970) {
 719          for ($a = 1970 ; $a <= $year; $a++) {
 720              $leaf = _adodb_is_leap_year($a);
 721              if ($leaf == true) {
 722                  $loop_table = $_month_table_leaf;
 723                  $_add_date = 366;
 724              } else {
 725                  $loop_table = $_month_table_normal;
 726                  $_add_date = 365;
 727              }
 728              if ($a < $year) {
 729                  $_total_date += $_add_date;
 730              } else {
 731                  for($b=1;$b<$mon;$b++) {
 732                      $_total_date += $loop_table[$b];
 733                  }
 734              }
 735          }
 736          $_total_date +=$day-1;
 737          $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
 738  
 739      } else {
 740          for ($a = 1969 ; $a >= $year; $a--) {
 741              $leaf = _adodb_is_leap_year($a);
 742              if ($leaf == true) {
 743                  $loop_table = $_month_table_leaf;
 744                  $_add_date = 366;
 745              } else {
 746                  $loop_table = $_month_table_normal;
 747                  $_add_date = 365;
 748              }
 749              if ($a > $year) { $_total_date += $_add_date;
 750              } else {
 751                  for($b=12;$b>$mon;$b--) {
 752                      $_total_date += $loop_table[$b];
 753                  }
 754              }
 755          }
 756          $_total_date += $loop_table[$mon] - $day;
 757  
 758          $_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
 759          $_day_time = $_day_power - $_day_time;
 760          $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
 761          if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction
 762          else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.
 763      }
 764      //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
 765      return $ret;
 766  }
 767  
 768  function adodb_gmstrftime($fmt, $ts=false)
 769  {
 770      return adodb_strftime($fmt,$ts,true);
 771  }
 772  
 773  // hack - convert to adodb_date
 774  function adodb_strftime($fmt, $ts=false,$is_gmt=false)
 775  {
 776  global $ADODB_DATE_LOCALE;
 777  
 778      if (!defined('ADODB_TEST_DATES')) {
 779          if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 780              if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer
 781                  return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts);
 782  
 783          }
 784      }
 785  
 786      if (empty($ADODB_DATE_LOCALE)) {
 787      /*
 788          $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am
 789          $sep = substr($tstr,2,1);
 790          $hasAM = strrpos($tstr,'M') !== false;
 791      */
 792          # see http://phplens.com/lens/lensforum/msgs.php?id=14865 for reasoning, and changelog for version 0.24
 793          $dstr = gmstrftime('%x',31366800); // 30 Dec 1970, 1 am
 794          $sep = substr($dstr,2,1);
 795          $tstr = strtoupper(gmstrftime('%X',31366800)); // 30 Dec 1970, 1 am
 796          $hasAM = strrpos($tstr,'M') !== false;
 797  
 798          $ADODB_DATE_LOCALE = array();
 799          $ADODB_DATE_LOCALE[] =  strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y';
 800          $ADODB_DATE_LOCALE[]  = ($hasAM) ? 'h:i:s a' : 'H:i:s';
 801  
 802      }
 803      $inpct = false;
 804      $fmtdate = '';
 805      for ($i=0,$max = strlen($fmt); $i < $max; $i++) {
 806          $ch = $fmt[$i];
 807          if ($ch == '%') {
 808              if ($inpct) {
 809                  $fmtdate .= '%';
 810                  $inpct = false;
 811              } else
 812                  $inpct = true;
 813          } else if ($inpct) {
 814  
 815              $inpct = false;
 816              switch($ch) {
 817              case '0':
 818              case '1':
 819              case '2':
 820              case '3':
 821              case '4':
 822              case '5':
 823              case '6':
 824              case '7':
 825              case '8':
 826              case '9':
 827              case 'E':
 828              case 'O':
 829                  /* ignore format modifiers */
 830                  $inpct = true;
 831                  break;
 832  
 833              case 'a': $fmtdate .= 'D'; break;
 834              case 'A': $fmtdate .= 'l'; break;
 835              case 'h':
 836              case 'b': $fmtdate .= 'M'; break;
 837              case 'B': $fmtdate .= 'F'; break;
 838              case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break;
 839              case 'C': $fmtdate .= '\C?'; break; // century
 840              case 'd': $fmtdate .= 'd'; break;
 841              case 'D': $fmtdate .= 'm/d/y'; break;
 842              case 'e': $fmtdate .= 'j'; break;
 843              case 'g': $fmtdate .= '\g?'; break; //?
 844              case 'G': $fmtdate .= '\G?'; break; //?
 845              case 'H': $fmtdate .= 'H'; break;
 846              case 'I': $fmtdate .= 'h'; break;
 847              case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd
 848              case 'm': $fmtdate .= 'm'; break;
 849              case 'M': $fmtdate .= 'i'; break;
 850              case 'n': $fmtdate .= "\n"; break;
 851              case 'p': $fmtdate .= 'a'; break;
 852              case 'r': $fmtdate .= 'h:i:s a'; break;
 853              case 'R': $fmtdate .= 'H:i:s'; break;
 854              case 'S': $fmtdate .= 's'; break;
 855              case 't': $fmtdate .= "\t"; break;
 856              case 'T': $fmtdate .= 'H:i:s'; break;
 857              case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based
 858              case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based
 859              case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break;
 860              case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break;
 861              case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based
 862              case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based
 863              case 'y': $fmtdate .= 'y'; break;
 864              case 'Y': $fmtdate .= 'Y'; break;
 865              case 'Z': $fmtdate .= 'T'; break;
 866              }
 867          } else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' ))
 868              $fmtdate .= "\\".$ch;
 869          else
 870              $fmtdate .= $ch;
 871      }
 872      //echo "fmt=",$fmtdate,"<br>";
 873      if ($ts === false) $ts = time();
 874      $ret = adodb_date($fmtdate, $ts, $is_gmt);
 875      return $ret;
 876  }
 877  


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref