[ Index ]
 

Code source de CMS made simple 1.0.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/adodb_lite/ -> adodb-time.inc.php (source)

   1  <?php
   2  /**
   3  ADOdb Date Library, part of the ADOdb abstraction library
   4  Download: http://phplens.com/phpeverywhere/
   5  
   6  PHP native date functions use integer timestamps for computations.
   7  Because of this, dates are restricted to the years 1901-2038 on Unix 
   8  and 1970-2038 on Windows due to integer overflow for dates beyond 
   9  those years. This library overcomes these limitations by replacing the 
  10  native function's signed integers (normally 32-bits) with PHP floating 
  11  point numbers (normally 64-bits).
  12  
  13  Dates from 100 A.D. to 3000 A.D. and later
  14  have been tested. The minimum is 100 A.D. as <100 will invoke the
  15  2 => 4 digit year conversion. The maximum is billions of years in the 
  16  future, but this is a theoretical limit as the computation of that year 
  17  would take too long with the current implementation of adodb_mktime().
  18  
  19  This library replaces native functions as follows:
  20  
  21  <pre>    
  22      getdate()  with  adodb_getdate()
  23      date()     with  adodb_date() 
  24      gmdate()   with  adodb_gmdate()
  25      mktime()   with  adodb_mktime()
  26      gmmktime() with  adodb_gmmktime()
  27      strftime() with  adodb_strftime()
  28      strftime() with  adodb_gmstrftime()
  29  </pre>
  30      
  31  The parameters are identical, except that adodb_date() accepts a subset
  32  of date()'s field formats. Mktime() will convert from local time to GMT, 
  33  and date() will convert from GMT to local time, but daylight savings is 
  34  not handled currently.
  35  
  36  This library is independant of the rest of ADOdb, and can be used
  37  as standalone code.
  38  
  39  PERFORMANCE
  40  
  41  For high speed, this library uses the native date functions where
  42  possible, and only switches to PHP code when the dates fall outside 
  43  the 32-bit signed integer range.
  44  
  45  GREGORIAN CORRECTION
  46  
  47  Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, 
  48  October 4, 1582 (Julian) was followed immediately by Friday, October 15, 
  49  1582 (Gregorian). 
  50  
  51  Since 0.06, we handle this correctly, so:
  52  
  53  adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) 
  54      == 24 * 3600 (1 day)
  55  
  56  =============================================================================
  57  
  58  COPYRIGHT
  59  
  60  (c) 2003-2005 John Lim and released under BSD-style license except for code by 
  61  jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
  62  and originally found at http://www.php.net/manual/en/function.mktime.php
  63  
  64  =============================================================================
  65  
  66  BUG REPORTS
  67  
  68  These should be posted to the ADOdb forums at
  69  
  70      http://phplens.com/lens/lensforum/topics.php?id=4
  71  
  72  =============================================================================
  73  
  74  FUNCTION DESCRIPTIONS
  75  
  76  
  77  ** FUNCTION adodb_getdate($date=false)
  78  
  79  Returns an array containing date information, as getdate(), but supports
  80  dates greater than 1901 to 2038. The local date/time format is derived from a 
  81  heuristic the first time adodb_getdate is called. 
  82       
  83       
  84  ** FUNCTION adodb_date($fmt, $timestamp = false)
  85  
  86  Convert a timestamp to a formatted local date. If $timestamp is not defined, the
  87  current timestamp is used. Unlike the function date(), it supports dates
  88  outside the 1901 to 2038 range.
  89  
  90  The format fields that adodb_date supports:
  91  
  92  <pre>
  93      a - "am" or "pm" 
  94      A - "AM" or "PM" 
  95      d - day of the month, 2 digits with leading zeros; i.e. "01" to "31" 
  96      D - day of the week, textual, 3 letters; e.g. "Fri" 
  97      F - month, textual, long; e.g. "January" 
  98      g - hour, 12-hour format without leading zeros; i.e. "1" to "12" 
  99      G - hour, 24-hour format without leading zeros; i.e. "0" to "23" 
 100      h - hour, 12-hour format; i.e. "01" to "12" 
 101      H - hour, 24-hour format; i.e. "00" to "23" 
 102      i - minutes; i.e. "00" to "59" 
 103      j - day of the month without leading zeros; i.e. "1" to "31" 
 104      l (lowercase 'L') - day of the week, textual, long; e.g. "Friday"  
 105      L - boolean for whether it is a leap year; i.e. "0" or "1" 
 106      m - month; i.e. "01" to "12" 
 107      M - month, textual, 3 letters; e.g. "Jan" 
 108      n - month without leading zeros; i.e. "1" to "12" 
 109      O - Difference to Greenwich time in hours; e.g. "+0200" 
 110      Q - Quarter, as in 1, 2, 3, 4 
 111      r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" 
 112      s - seconds; i.e. "00" to "59" 
 113      S - English ordinal suffix for the day of the month, 2 characters; 
 114                     i.e. "st", "nd", "rd" or "th" 
 115      t - number of days in the given month; i.e. "28" to "31"
 116      T - Timezone setting of this machine; e.g. "EST" or "MDT" 
 117      U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)  
 118      w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) 
 119      Y - year, 4 digits; e.g. "1999" 
 120      y - year, 2 digits; e.g. "99" 
 121      z - day of the year; i.e. "0" to "365" 
 122      Z - timezone offset in seconds (i.e. "-43200" to "43200"). 
 123                     The offset for timezones west of UTC is always negative, 
 124                  and for those east of UTC is always positive. 
 125  </pre>
 126  
 127  Unsupported:
 128  <pre>
 129      B - Swatch Internet time 
 130      I (capital i) - "1" if Daylight Savings Time, "0" otherwise.
 131      W - ISO-8601 week number of year, weeks starting on Monday 
 132  
 133  </pre>
 134  
 135  
 136  ** FUNCTION adodb_date2($fmt, $isoDateString = false)
 137  Same as adodb_date, but 2nd parameter accepts iso date, eg.
 138  
 139    adodb_date2('d-M-Y H:i','2003-12-25 13:01:34');
 140  
 141    
 142  ** FUNCTION adodb_gmdate($fmt, $timestamp = false)
 143  
 144  Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the
 145  current timestamp is used. Unlike the function date(), it supports dates
 146  outside the 1901 to 2038 range.
 147  
 148  
 149  ** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year])
 150  
 151  Converts a local date to a unix timestamp.  Unlike the function mktime(), it supports
 152  dates outside the 1901 to 2038 range. All parameters are optional.
 153  
 154  
 155  ** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year])
 156  
 157  Converts a gmt date to a unix timestamp.  Unlike the function gmmktime(), it supports
 158  dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters
 159  are currently compulsory.
 160  
 161  ** FUNCTION adodb_gmstrftime($fmt, $timestamp = false)
 162  Convert a timestamp to a formatted GMT date.
 163  
 164  ** FUNCTION adodb_strftime($fmt, $timestamp = false)
 165  
 166  Convert a timestamp to a formatted local date. Internally converts $fmt into 
 167  adodb_date format, then echo result.
 168  
 169  For best results, you can define the local date format yourself. Define a global
 170  variable $ADODB_DATE_LOCALE which is an array, 1st element is date format using
 171  adodb_date syntax, and 2nd element is the time format, also in adodb_date syntax.
 172  
 173      eg. $ADODB_DATE_LOCALE = array('d/m/Y','H:i:s');
 174      
 175      Supported format codes:
 176  
 177  <pre>
 178      %a - abbreviated weekday name according to the current locale 
 179      %A - full weekday name according to the current locale 
 180      %b - abbreviated month name according to the current locale 
 181      %B - full month name according to the current locale 
 182      %c - preferred date and time representation for the current locale 
 183      %d - day of the month as a decimal number (range 01 to 31) 
 184      %D - same as %m/%d/%y 
 185      %e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') 
 186      %h - same as %b
 187      %H - hour as a decimal number using a 24-hour clock (range 00 to 23) 
 188      %I - hour as a decimal number using a 12-hour clock (range 01 to 12) 
 189      %m - month as a decimal number (range 01 to 12) 
 190      %M - minute as a decimal number 
 191      %n - newline character 
 192      %p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale 
 193      %r - time in a.m. and p.m. notation 
 194      %R - time in 24 hour notation 
 195      %S - second as a decimal number 
 196      %t - tab character 
 197      %T - current time, equal to %H:%M:%S 
 198      %x - preferred date representation for the current locale without the time 
 199      %X - preferred time representation for the current locale without the date 
 200      %y - year as a decimal number without a century (range 00 to 99) 
 201      %Y - year as a decimal number including the century 
 202      %Z - time zone or name or abbreviation 
 203      %% - a literal `%' character 
 204  </pre>    
 205  
 206      Unsupported codes:
 207  <pre>
 208      %C - century number (the year divided by 100 and truncated to an integer, range 00 to 99) 
 209      %g - like %G, but without the century. 
 210      %G - The 4-digit year corresponding to the ISO week number (see %V). 
 211           This has the same format and value as %Y, except that if the ISO week number belongs 
 212           to the previous or next year, that year is used instead. 
 213      %j - day of the year as a decimal number (range 001 to 366) 
 214      %u - weekday as a decimal number [1,7], with 1 representing Monday 
 215      %U - week number of the current year as a decimal number, starting 
 216          with the first Sunday as the first day of the first week 
 217      %V - The ISO 8601:1988 week number of the current year as a decimal number, 
 218           range 01 to 53, where week 1 is the first week that has at least 4 days in the 
 219           current year, and with Monday as the first day of the week. (Use %G or %g for 
 220           the year component that corresponds to the week number for the specified timestamp.) 
 221      %w - day of the week as a decimal, Sunday being 0 
 222      %W - week number of the current year as a decimal number, starting with the 
 223           first Monday as the first day of the first week 
 224  </pre>
 225  
 226  =============================================================================
 227  
 228  NOTES
 229  
 230  Useful url for generating test timestamps:
 231      http://www.4webhelp.net/us/timestamp.php
 232  
 233  Possible future optimizations include 
 234  
 235  a. Using an algorithm similar to Plauger's in "The Standard C Library" 
 236  (page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not 
 237  work outside 32-bit signed range, so i decided not to implement it.
 238  
 239  b. Implement daylight savings, which looks awfully complicated, see
 240      http://webexhibits.org/daylightsaving/
 241  
 242  
 243  CHANGELOG
 244  - 08 Sept 2005 0.22
 245  In adodb_date2(), $is_gmt not supported properly. Fixed.
 246  
 247  - 18 July  2005 0.21
 248  In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat.
 249  Added support for negative months in adodb_mktime().
 250  
 251  - 24 Feb 2005 0.20
 252  Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date().
 253  
 254  - 21 Dec 2004 0.17
 255  In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false. 
 256  Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro.
 257  
 258  - 17 Nov 2004 0.16
 259  Removed intval typecast in adodb_mktime() for secs, allowing:
 260       adodb_mktime(0,0,0 + 2236672153,1,1,1934);
 261  Suggested by Ryan.
 262  
 263  - 18 July 2004 0.15
 264  All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. 
 265  This brings it more in line with mktime (still not identical).
 266  
 267  - 23 June 2004 0.14
 268  
 269  Allow you to define your own daylights savings function, adodb_daylight_sv.
 270  If the function is defined (somewhere in an include), then you can correct for daylights savings.
 271  
 272  In this example, we apply daylights savings in June or July, adding one hour. This is extremely
 273  unrealistic as it does not take into account time-zone, geographic location, current year.
 274  
 275  function adodb_daylight_sv(&$arr, $is_gmt)
 276  {
 277      if ($is_gmt) return;
 278      $m = $arr['mon'];
 279      if ($m == 6 || $m == 7) $arr['hours'] += 1;
 280  }
 281  
 282  This is only called by adodb_date() and not by adodb_mktime(). 
 283  
 284  The format of $arr is
 285  Array ( 
 286     [seconds] => 0 
 287     [minutes] => 0 
 288     [hours] => 0 
 289     [mday] => 1      # day of month, eg 1st day of the month
 290     [mon] => 2       # month (eg. Feb)
 291     [year] => 2102 
 292     [yday] => 31     # days in current year
 293     [leap] =>        # true if leap year
 294     [ndays] => 28    # no of days in current month
 295     ) 
 296     
 297  
 298  - 28 Apr 2004 0.13
 299  Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov.
 300  
 301  - 20 Mar 2004 0.12
 302  Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32.
 303  
 304  - 26 Oct 2003 0.11
 305  Because of daylight savings problems (some systems apply daylight savings to 
 306  January!!!), changed adodb_get_gmt_diff() to ignore daylight savings.
 307  
 308  - 9 Aug 2003 0.10
 309  Fixed bug with dates after 2038. 
 310  See http://phplens.com/lens/lensforum/msgs.php?id=6980
 311  
 312  - 1 July 2003 0.09
 313  Added support for Q (Quarter).
 314  Added adodb_date2(), which accepts ISO date in 2nd param
 315  
 316  - 3 March 2003 0.08
 317  Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS
 318  if you want PHP to handle negative timestamps between 1901 to 1969.
 319  
 320  - 27 Feb 2003 0.07
 321  All negative numbers handled by adodb now because of RH 7.3+ problems.
 322  See http://bugs.php.net/bug.php?id=20048&edit=2
 323  
 324  - 4 Feb 2003 0.06
 325  Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates
 326  are now correctly handled.
 327  
 328  - 29 Jan 2003 0.05
 329  
 330  Leap year checking differs under Julian calendar (pre 1582). Also
 331  leap year code optimized by checking for most common case first.
 332  
 333  We also handle month overflow correctly in mktime (eg month set to 13).
 334  
 335  Day overflow for less than one month's days is supported.
 336  
 337  - 28 Jan 2003 0.04
 338  
 339  Gregorian correction handled. In PHP5, we might throw an error if 
 340  mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10.
 341  Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582.
 342  
 343  - 27 Jan 2003 0.03
 344  
 345  Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION.
 346  Fixed calculation of days since start of year for <1970. 
 347  
 348  - 27 Jan 2003 0.02
 349  
 350  Changed _adodb_getdate() to inline leap year checking for better performance.
 351  Fixed problem with time-zones west of GMT +0000.
 352  
 353  - 24 Jan 2003 0.01
 354  
 355  First implementation.
 356  */
 357  
 358  
 359  /* Initialization */
 360  
 361  /*
 362      Version Number
 363  */
 364  define('ADODB_DATE_VERSION',0.22);
 365  
 366  /*
 367      This code was originally for windows. But apparently this problem happens 
 368      also with Linux, RH 7.3 and later!
 369      
 370      glibc-2.2.5-34 and greater has been changed to return -1 for dates <
 371      1970.  This used to work.  The problem exists with RedHat 7.3 and 8.0
 372      echo (mktime(0, 0, 0, 1, 1, 1960));  // prints -1
 373      
 374      References:
 375       http://bugs.php.net/bug.php?id=20048&edit=2
 376       http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html
 377  */
 378  
 379  if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
 380  
 381  function adodb_date_test_date($y1,$m,$d=13)
 382  {
 383      $t = adodb_mktime(0,0,0,$m,$d,$y1);
 384      $rez = adodb_date('Y-n-j H:i:s',$t);
 385      if ("$y1-$m-$d 00:00:00" != $rez) {
 386          print "<b>$y1 error, expected=$y1-$m-$d 00:00:00, adodb=$rez</b><br>";
 387          return false;
 388      }
 389      return true;
 390  }
 391  
 392  function adodb_date_test_strftime($fmt)
 393  {
 394      $s1 = strftime($fmt);
 395      $s2 = adodb_strftime($fmt);
 396      
 397      if ($s1 == $s2) return true;
 398      
 399      echo "error for $fmt,  strftime=$s1, $adodb=$s2<br>";
 400      return false;
 401  }
 402  
 403  /**
 404       Test Suite
 405  */
 406  function adodb_date_test()
 407  {
 408      
 409      error_reporting(E_ALL);
 410      print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>";
 411      @set_time_limit(0);
 412      $fail = false;
 413      
 414      // This flag disables calling of PHP native functions, so we can properly test the code
 415      if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
 416      
 417      adodb_date_test_strftime('%Y %m %x %X');
 418      adodb_date_test_strftime("%A %d %B %Y");
 419      adodb_date_test_strftime("%H %M S");
 420      
 421      $t = adodb_mktime(0,0,0);
 422      if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
 423      
 424      $t = adodb_mktime(0,0,0,6,1,2102);
 425      if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
 426      
 427      $t = adodb_mktime(0,0,0,2,1,2102);
 428      if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
 429      
 430      
 431      print "<p>Testing gregorian <=> julian conversion<p>";
 432      $t = adodb_mktime(0,0,0,10,11,1492);
 433      //http://www.holidayorigins.com/html/columbus_day.html - Friday check
 434      if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>';
 435      
 436      $t = adodb_mktime(0,0,0,2,29,1500);
 437      if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>';
 438      
 439      $t = adodb_mktime(0,0,0,2,29,1700);
 440      if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>';
 441      
 442      print  adodb_mktime(0,0,0,10,4,1582).' ';
 443      print adodb_mktime(0,0,0,10,15,1582);
 444      $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582));
 445      if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>";
 446          
 447      print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>";
 448      print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>";
 449      
 450      print "<p>Testing overflow<p>";
 451      
 452      $t = adodb_mktime(0,0,0,3,33,1965);
 453      if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>';
 454      $t = adodb_mktime(0,0,0,4,33,1971);
 455      if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>';
 456      $t = adodb_mktime(0,0,0,1,60,1965);
 457      if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>';
 458      $t = adodb_mktime(0,0,0,12,32,1965);
 459      if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>';
 460      $t = adodb_mktime(0,0,0,12,63,1965);
 461      if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>';
 462      $t = adodb_mktime(0,0,0,13,3,1965);
 463      if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>';
 464      
 465      print "Testing 2-digit => 4-digit year conversion<p>";
 466      if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>";
 467      if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>";
 468      if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>";
 469      if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>";
 470      if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>";
 471      if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
 472      if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
 473      
 474      // Test string formating
 475      print "<p>Testing date formating</p>";
 476      $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C822 r s t U w y Y z Z 2003';
 477      $s1 = date($fmt,0);
 478      $s2 = adodb_date($fmt,0);
 479      if ($s1 != $s2) {
 480          print " date() 0 failed<br>$s1<br>$s2<br>";
 481      }
 482      flush();
 483      for ($i=100; --$i > 0; ) {
 484  
 485          $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000);
 486          $s1 = date($fmt,$ts);
 487          $s2 = adodb_date($fmt,$ts);
 488          //print "$s1 <br>$s2 <p>";
 489          $pos = strcmp($s1,$s2);
 490  
 491          if (($s1) != ($s2)) {
 492              for ($j=0,$k=strlen($s1); $j < $k; $j++) {
 493                  if ($s1[$j] != $s2[$j]) {
 494                      print substr($s1,$j).' ';
 495                      break;
 496                  }
 497              }
 498              print "<b>Error date(): $ts<br><pre> 
 499  &nbsp; \"$s1\" (date len=".strlen($s1).")
 500  &nbsp; \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>";
 501              $fail = true;
 502          }
 503          
 504          $a1 = getdate($ts);
 505          $a2 = adodb_getdate($ts);
 506          $rez = array_diff($a1,$a2);
 507          if (sizeof($rez)>0) {
 508              print "<b>Error getdate() $ts</b><br>";
 509                  print_r($a1);
 510              print "<br>";
 511                  print_r($a2);
 512              print "<p>";
 513              $fail = true;
 514          }
 515      }
 516      
 517      // Test generation of dates outside 1901-2038
 518      print "<p>Testing random dates between 100 and 4000</p>";
 519      adodb_date_test_date(100,1);
 520      for ($i=100; --$i >= 0;) {
 521          $y1 = 100+rand(0,1970-100);
 522          $m = rand(1,12);
 523          adodb_date_test_date($y1,$m);
 524          
 525          $y1 = 3000-rand(0,3000-1970);
 526          adodb_date_test_date($y1,$m);
 527      }
 528      print '<p>';
 529      $start = 1960+rand(0,10);
 530      $yrs = 12;
 531      $i = 365.25*86400*($start-1970);
 532      $offset = 36000+rand(10000,60000);
 533      $max = 365*$yrs*86400;
 534      $lastyear = 0;
 535      
 536      // we generate a timestamp, convert it to a date, and convert it back to a timestamp
 537      // and check if the roundtrip broke the original timestamp value.
 538      print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
 539      $cnt = 0;
 540      for ($max += $i; $i < $max; $i += $offset) {
 541          $ret = adodb_date('m,d,Y,H,i,s',$i);
 542          $arr = explode(',',$ret);
 543          if ($lastyear != $arr[2]) {
 544              $lastyear = $arr[2];
 545              print " $lastyear ";
 546              flush();
 547          }
 548          $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]);
 549          if ($i != $newi) {
 550              print "Error at $i, adodb_mktime returned $newi ($ret)";
 551              $fail = true;
 552              break;
 553          }
 554          $cnt += 1;
 555      }
 556      echo "Tested $cnt dates<br>";
 557      if (!$fail) print "<p>Passed !</p>";
 558      else print "<p><b>Failed</b> :-(</p>";
 559  }
 560  
 561  /**
 562      Returns day of week, 0 = Sunday,... 6=Saturday. 
 563      Algorithm from PEAR::Date_Calc
 564  */
 565  function adodb_dow($year, $month, $day)
 566  {
 567  /*
 568  Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and 
 569  proclaimed that from that time onwards 3 days would be dropped from the calendar 
 570  every 400 years.
 571  
 572  Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). 
 573  */
 574      if ($year <= 1582) {
 575          if ($year < 1582 || 
 576              ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
 577           else
 578              $greg_correction = 0;
 579      } else
 580          $greg_correction = 0;
 581      
 582      if($month > 2)
 583          $month -= 2;
 584      else {
 585          $month += 10;
 586          $year--;
 587      }
 588      
 589      $day =  floor((13 * $month - 1) / 5) +
 590              $day + ($year % 100) +
 591              floor(($year % 100) / 4) +
 592              floor(($year / 100) / 4) - 2 *
 593              floor($year / 100) + 77 + $greg_correction;
 594      
 595      return $day - 7 * floor($day / 7);
 596  }
 597  
 598  
 599  /**
 600   Checks for leap year, returns true if it is. No 2-digit year check. Also 
 601   handles julian calendar correctly.
 602  */
 603  function _adodb_is_leap_year($year) 
 604  {
 605      if ($year % 4 != 0) return false;
 606      
 607      if ($year % 400 == 0) {
 608          return true;
 609      // if gregorian calendar (>1582), century not-divisible by 400 is not leap
 610      } else if ($year > 1582 && $year % 100 == 0 ) {
 611          return false;
 612      } 
 613      
 614      return true;
 615  }
 616  
 617  
 618  /**
 619   checks for leap year, returns true if it is. Has 2-digit year check
 620  */
 621  function adodb_is_leap_year($year) 
 622  {
 623      return  _adodb_is_leap_year(adodb_year_digit_check($year));
 624  }
 625  
 626  /**
 627      Fix 2-digit years. Works for any century.
 628       Assumes that if 2-digit is more than 30 years in future, then previous century.
 629  */
 630  function adodb_year_digit_check($y) 
 631  {
 632      if ($y < 100) {
 633      
 634          $yr = (integer) date("Y");
 635          $century = (integer) ($yr /100);
 636          
 637          if ($yr%100 > 50) {
 638              $c1 = $century + 1;
 639              $c0 = $century;
 640          } else {
 641              $c1 = $century;
 642              $c0 = $century - 1;
 643          }
 644          $c1 *= 100;
 645          // if 2-digit year is less than 30 years in future, set it to this century
 646          // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
 647          if (($y + $c1) < $yr+30) $y = $y + $c1;
 648          else $y = $y + $c0*100;
 649      }
 650      return $y;
 651  }
 652  
 653  /**
 654   get local time zone offset from GMT
 655  */
 656  function adodb_get_gmt_diff() 
 657  {
 658  static $TZ;
 659      if (isset($TZ)) return $TZ;
 660      
 661      $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0);
 662      return $TZ;
 663  }
 664  
 665  /**
 666      Returns an array with date info.
 667  */
 668  function adodb_getdate($d=false,$fast=false)
 669  {
 670      if ($d === false) return getdate();
 671      if (!defined('ADODB_TEST_DATES')) {
 672          if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 673              if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
 674                  return @getdate($d);
 675          }
 676      }
 677      return _adodb_getdate($d);
 678  }
 679  
 680  /*
 681  // generate $YRS table for _adodb_getdate()
 682  function adodb_date_gentable($out=true)
 683  {
 684  
 685      for ($i=1970; $i >= 1600; $i-=10) {
 686          $s = adodb_gmmktime(0,0,0,1,1,$i);
 687          echo "$i => $s,<br>";    
 688      }
 689  }
 690  adodb_date_gentable();
 691  
 692  for ($i=1970; $i > 1500; $i--) {
 693  
 694  echo "<hr>$i ";
 695      adodb_date_test_date($i,1,1);
 696  }
 697  
 698  */
 699  
 700  
 701  $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
 702  $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
 703      
 704  function adodb_validdate($y,$m,$d)
 705  {
 706  global $_month_table_normal,$_month_table_leaf;
 707  
 708      if (_adodb_is_leap_year($y)) $marr =& $_month_table_leaf;
 709      else $marr =& $_month_table_normal;
 710      
 711      if ($m > 12 || $m < 1) return false;
 712      
 713      if ($d > 31 || $d < 1) return false;
 714      
 715      if ($marr[$m] < $d) return false;
 716      
 717      if ($y < 1000 && $y > 3000) return false;
 718      
 719      return true;
 720  }
 721  
 722  /**
 723      Low-level function that returns the getdate() array. We have a special
 724      $fast flag, which if set to true, will return fewer array values,
 725      and is much faster as it does not calculate dow, etc.
 726  */
 727  function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
 728  {
 729  static $YRS;
 730  global $_month_table_normal,$_month_table_leaf;
 731  
 732      $d =  $origd - ($is_gmt ? 0 : adodb_get_gmt_diff());
 733      
 734      $_day_power = 86400;
 735      $_hour_power = 3600;
 736      $_min_power = 60;
 737      
 738      if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction 
 739      
 740      $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
 741      $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
 742      
 743      $d366 = $_day_power * 366;
 744      $d365 = $_day_power * 365;
 745      
 746      if ($d < 0) {
 747          
 748          if (empty($YRS)) $YRS = array(
 749              1970 => 0,
 750              1960 => -315619200,
 751              1950 => -631152000,
 752              1940 => -946771200,
 753              1930 => -1262304000,
 754              1920 => -1577923200,
 755              1910 => -1893456000,
 756              1900 => -2208988800,
 757              1890 => -2524521600,
 758              1880 => -2840140800,
 759              1870 => -3155673600,
 760              1860 => -3471292800,
 761              1850 => -3786825600,
 762              1840 => -4102444800,
 763              1830 => -4417977600,
 764              1820 => -4733596800,
 765              1810 => -5049129600,
 766              1800 => -5364662400,
 767              1790 => -5680195200,
 768              1780 => -5995814400,
 769              1770 => -6311347200,
 770              1760 => -6626966400,
 771              1750 => -6942499200,
 772              1740 => -7258118400,
 773              1730 => -7573651200,
 774              1720 => -7889270400,
 775              1710 => -8204803200,
 776              1700 => -8520336000,
 777              1690 => -8835868800,
 778              1680 => -9151488000,
 779              1670 => -9467020800,
 780              1660 => -9782640000,
 781              1650 => -10098172800,
 782              1640 => -10413792000,
 783              1630 => -10729324800,
 784              1620 => -11044944000,
 785              1610 => -11360476800,
 786              1600 => -11676096000);
 787  
 788          if ($is_gmt) $origd = $d;
 789          // The valid range of a 32bit signed timestamp is typically from 
 790          // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
 791          //
 792          
 793          # old algorithm iterates through all years. new algorithm does it in
 794          # 10 year blocks
 795          
 796          /*
 797          # old algo
 798          for ($a = 1970 ; --$a >= 0;) {
 799              $lastd = $d;
 800              
 801              if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
 802              else $d += $d365;
 803              
 804              if ($d >= 0) {
 805                  $year = $a;
 806                  break;
 807              }
 808          }
 809          */
 810          
 811          $lastsecs = 0;
 812          $lastyear = 1970;
 813          foreach($YRS as $year => $secs) {
 814              if ($d >= $secs) {
 815                  $a = $lastyear;
 816                  break;
 817              }
 818              $lastsecs = $secs;
 819              $lastyear = $year;
 820          }
 821          
 822          $d -= $lastsecs;
 823          if (!isset($a)) $a = $lastyear;
 824          
 825          //echo ' yr=',$a,' ', $d,'.';
 826          
 827          for (; --$a >= 0;) {
 828              $lastd = $d;
 829              
 830              if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
 831              else $d += $d365;
 832              
 833              if ($d >= 0) {
 834                  $year = $a;
 835                  break;
 836              }
 837          }
 838          /**/
 839          
 840          $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
 841          
 842          $d = $lastd;
 843          $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
 844          for ($a = 13 ; --$a > 0;) {
 845              $lastd = $d;
 846              $d += $mtab[$a] * $_day_power;
 847              if ($d >= 0) {
 848                  $month = $a;
 849                  $ndays = $mtab[$a];
 850                  break;
 851              }
 852          }
 853          
 854          $d = $lastd;
 855          $day = $ndays + ceil(($d+1) / ($_day_power));
 856  
 857          $d += ($ndays - $day+1)* $_day_power;
 858          $hour = floor($d/$_hour_power);
 859      
 860      } else {
 861          for ($a = 1970 ;; $a++) {
 862              $lastd = $d;
 863              
 864              if ($leaf = _adodb_is_leap_year($a)) $d -= $d366;
 865              else $d -= $d365;
 866              if ($d < 0) {
 867                  $year = $a;
 868                  break;
 869              }
 870          }
 871          $secsInYear = $lastd;
 872          $d = $lastd;
 873          $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
 874          for ($a = 1 ; $a <= 12; $a++) {
 875              $lastd = $d;
 876              $d -= $mtab[$a] * $_day_power;
 877              if ($d < 0) {
 878                  $month = $a;
 879                  $ndays = $mtab[$a];
 880                  break;
 881              }
 882          }
 883          $d = $lastd;
 884          $day = ceil(($d+1) / $_day_power);
 885          $d = $d - ($day-1) * $_day_power;
 886          $hour = floor($d /$_hour_power);
 887      }
 888      
 889      $d -= $hour * $_hour_power;
 890      $min = floor($d/$_min_power);
 891      $secs = $d - $min * $_min_power;
 892      if ($fast) {
 893          return array(
 894          'seconds' => $secs,
 895          'minutes' => $min,
 896          'hours' => $hour,
 897          'mday' => $day,
 898          'mon' => $month,
 899          'year' => $year,
 900          'yday' => floor($secsInYear/$_day_power),
 901          'leap' => $leaf,
 902          'ndays' => $ndays
 903          );
 904      }
 905      
 906      
 907      $dow = adodb_dow($year,$month,$day);
 908  
 909      return array(
 910          'seconds' => $secs,
 911          'minutes' => $min,
 912          'hours' => $hour,
 913          'mday' => $day,
 914          'wday' => $dow,
 915          'mon' => $month,
 916          'year' => $year,
 917          'yday' => floor($secsInYear/$_day_power),
 918          'weekday' => gmdate('l',$_day_power*(3+$dow)),
 919          'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
 920          0 => $origd
 921      );
 922  }
 923  
 924  function adodb_gmdate($fmt,$d=false)
 925  {
 926      return adodb_date($fmt,$d,true);
 927  }
 928  
 929  // accepts unix timestamp and iso date format in $d
 930  function adodb_date2($fmt, $d=false, $is_gmt=false)
 931  {
 932      if ($d !== false) {
 933          if (!preg_match( 
 934              "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 
 935              ($d), $rr)) return adodb_date($fmt,false,$is_gmt);
 936  
 937          if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
 938      
 939          // h-m-s-MM-DD-YY
 940          if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt);
 941          else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt);
 942      }
 943      
 944      return adodb_date($fmt,$d,$is_gmt);
 945  }
 946  
 947  
 948  /**
 949      Return formatted date based on timestamp $d
 950  */
 951  function adodb_date($fmt,$d=false,$is_gmt=false)
 952  {
 953  static $daylight;
 954  
 955      if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
 956      if (!defined('ADODB_TEST_DATES')) {
 957          if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 958              if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
 959                  return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
 960  
 961          }
 962      }
 963      $_day_power = 86400;
 964      
 965      $arr = _adodb_getdate($d,true,$is_gmt);
 966      
 967      if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
 968      if ($daylight) adodb_daylight_sv($arr, $is_gmt);
 969      
 970      $year = $arr['year'];
 971      $month = $arr['mon'];
 972      $day = $arr['mday'];
 973      $hour = $arr['hours'];
 974      $min = $arr['minutes'];
 975      $secs = $arr['seconds'];
 976      
 977      $max = strlen($fmt);
 978      $dates = '';
 979      
 980      /*
 981          at this point, we have the following integer vars to manipulate:
 982          $year, $month, $day, $hour, $min, $secs
 983      */
 984      for ($i=0; $i < $max; $i++) {
 985          switch($fmt[$i]) {
 986          case 'T': $dates .= date('T');break;
 987          // YEAR
 988          case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
 989          case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
 990          
 991              // 4.3.11 uses '04 Jun 2004'
 992              // 4.3.8 uses  ' 4 Jun 2004'
 993              $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '        
 994                  . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
 995              
 996              if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; 
 997              
 998              if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
 999              
1000              if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
1001              
1002              $gmt = adodb_get_gmt_diff();
1003              $dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
1004                  
1005          case 'Y': $dates .= $year; break;
1006          case 'y': $dates .= substr($year,strlen($year)-2,2); break;
1007          // MONTH
1008          case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
1009          case 'Q': $dates .= ($month+3)>>2; break;
1010          case 'n': $dates .= $month; break;
1011          case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
1012          case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
1013          // DAY
1014          case 't': $dates .= $arr['ndays']; break;
1015          case 'z': $dates .= $arr['yday']; break;
1016          case 'w': $dates .= adodb_dow($year,$month,$day); break;
1017          case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
1018          case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
1019          case 'j': $dates .= $day; break;
1020          case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
1021          case 'S': 
1022              $d10 = $day % 10;
1023              if ($d10 == 1) $dates .= 'st';
1024              else if ($d10 == 2 && $day != 12) $dates .= 'nd';
1025              else if ($d10 == 3) $dates .= 'rd';
1026              else $dates .= 'th';
1027              break;
1028              
1029          // HOUR
1030          case 'Z':
1031              $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break;
1032          case 'O': 
1033              $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff();
1034              $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
1035              
1036          case 'H': 
1037              if ($hour < 10) $dates .= '0'.$hour; 
1038              else $dates .= $hour; 
1039              break;
1040          case 'h': 
1041              if ($hour > 12) $hh = $hour - 12; 
1042              else {
1043                  if ($hour == 0) $hh = '12'; 
1044                  else $hh = $hour;
1045              }
1046              
1047              if ($hh < 10) $dates .= '0'.$hh;
1048              else $dates .= $hh;
1049              break;
1050              
1051          case 'G': 
1052              $dates .= $hour;
1053              break;
1054              
1055          case 'g':
1056              if ($hour > 12) $hh = $hour - 12; 
1057              else {
1058                  if ($hour == 0) $hh = '12'; 
1059                  else $hh = $hour; 
1060              }
1061              $dates .= $hh;
1062              break;
1063          // MINUTES
1064          case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
1065          // SECONDS
1066          case 'U': $dates .= $d; break;
1067          case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
1068          // AM/PM
1069          // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
1070          case 'a':
1071              if ($hour>=12) $dates .= 'pm';
1072              else $dates .= 'am';
1073              break;
1074          case 'A':
1075              if ($hour>=12) $dates .= 'PM';
1076              else $dates .= 'AM';
1077              break;
1078          default:
1079              $dates .= $fmt[$i]; break;
1080          // ESCAPE
1081          case "\\": 
1082              $i++;
1083              if ($i < $max) $dates .= $fmt[$i];
1084              break;
1085          }
1086      }
1087      return $dates;
1088  }
1089  
1090  /**
1091      Returns a timestamp given a GMT/UTC time. 
1092      Note that $is_dst is not implemented and is ignored.
1093  */
1094  function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
1095  {
1096      return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
1097  }
1098  
1099  /**
1100      Return a timestamp given a local time. Originally by jackbbs.
1101      Note that $is_dst is not implemented and is ignored.
1102      
1103      Not a very fast algorithm - O(n) operation. Could be optimized to O(1).
1104  */
1105  function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false) 
1106  {
1107      if (!defined('ADODB_TEST_DATES')) {
1108  
1109          if ($mon === false) {
1110              return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
1111          }
1112          
1113          // for windows, we don't check 1970 because with timezone differences, 
1114          // 1 Jan 1970 could generate negative timestamp, which is illegal
1115          if (1971 < $year && $year < 2038
1116              || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
1117              ) {
1118                  return $is_gmt ?
1119                      @gmmktime($hr,$min,$sec,$mon,$day,$year):
1120                      @mktime($hr,$min,$sec,$mon,$day,$year);
1121              }
1122      }
1123      
1124      $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff();
1125  
1126      /*
1127      # disabled because some people place large values in $sec.
1128      # however we need it for $mon because we use an array...
1129      $hr = intval($hr);
1130      $min = intval($min);
1131      $sec = intval($sec);
1132      */
1133      $mon = intval($mon);
1134      $day = intval($day);
1135      $year = intval($year);
1136      
1137      
1138      $year = adodb_year_digit_check($year);
1139  
1140      if ($mon > 12) {
1141          $y = floor($mon / 12);
1142          $year += $y;
1143          $mon -= $y*12;
1144      } else if ($mon < 1) {
1145          $y = ceil((1-$mon) / 12);
1146          $year -= $y;
1147          $mon += $y*12;
1148      }
1149      
1150      $_day_power = 86400;
1151      $_hour_power = 3600;
1152      $_min_power = 60;
1153      
1154      $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
1155      $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
1156      
1157      $_total_date = 0;
1158      if ($year >= 1970) {
1159          for ($a = 1970 ; $a <= $year; $a++) {
1160              $leaf = _adodb_is_leap_year($a);
1161              if ($leaf == true) {
1162                  $loop_table = $_month_table_leaf;
1163                  $_add_date = 366;
1164              } else {
1165                  $loop_table = $_month_table_normal;
1166                  $_add_date = 365;
1167              }
1168              if ($a < $year) { 
1169                  $_total_date += $_add_date;
1170              } else {
1171                  for($b=1;$b<$mon;$b++) {
1172                      $_total_date += $loop_table[$b];
1173                  }
1174              }
1175          }
1176          $_total_date +=$day-1;
1177          $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
1178      
1179      } else {
1180          for ($a = 1969 ; $a >= $year; $a--) {
1181              $leaf = _adodb_is_leap_year($a);
1182              if ($leaf == true) {
1183                  $loop_table = $_month_table_leaf;
1184                  $_add_date = 366;
1185              } else {
1186                  $loop_table = $_month_table_normal;
1187                  $_add_date = 365;
1188              }
1189              if ($a > $year) { $_total_date += $_add_date;
1190              } else {
1191                  for($b=12;$b>$mon;$b--) {
1192                      $_total_date += $loop_table[$b];
1193                  }
1194              }
1195          }
1196          $_total_date += $loop_table[$mon] - $day;
1197          
1198          $_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
1199          $_day_time = $_day_power - $_day_time;
1200          $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
1201          if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction
1202          else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.
1203      } 
1204      //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
1205      return $ret;
1206  }
1207  
1208  function adodb_gmstrftime($fmt, $ts=false)
1209  {
1210      return adodb_strftime($fmt,$ts,true);
1211  }
1212  
1213  // hack - convert to adodb_date
1214  function adodb_strftime($fmt, $ts=false,$is_gmt=false)
1215  {
1216  global $ADODB_DATE_LOCALE;
1217  
1218      if (!defined('ADODB_TEST_DATES')) {
1219          if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
1220              if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer
1221                  return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts);
1222  
1223          }
1224      }
1225      
1226      if (empty($ADODB_DATE_LOCALE)) {
1227          $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am
1228          $sep = substr($tstr,2,1);
1229          $hasAM = strrpos($tstr,'M') !== false;
1230          
1231          $ADODB_DATE_LOCALE = array();
1232          $ADODB_DATE_LOCALE[] =  strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y';    
1233          $ADODB_DATE_LOCALE[]  = ($hasAM) ? 'h:i:s a' : 'H:i:s';
1234              
1235      }
1236      $inpct = false;
1237      $fmtdate = '';
1238      for ($i=0,$max = strlen($fmt); $i < $max; $i++) {
1239          $ch = $fmt[$i];
1240          if ($ch == '%') {
1241              if ($inpct) {
1242                  $fmtdate .= '%';
1243                  $inpct = false;
1244              } else
1245                  $inpct = true;
1246          } else if ($inpct) {
1247          
1248              $inpct = false;
1249              switch($ch) {
1250              case '0':
1251              case '1':
1252              case '2':
1253              case '3':
1254              case '4':
1255              case '5':
1256              case '6':
1257              case '7':
1258              case '8':
1259              case '9':
1260              case 'E':
1261              case 'O':
1262                  /* ignore format modifiers */
1263                  $inpct = true; 
1264                  break;
1265                  
1266              case 'a': $fmtdate .= 'D'; break;
1267              case 'A': $fmtdate .= 'l'; break;
1268              case 'h':
1269              case 'b': $fmtdate .= 'M'; break;
1270              case 'B': $fmtdate .= 'F'; break;
1271              case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break;
1272              case 'C': $fmtdate .= '\C?'; break; // century
1273              case 'd': $fmtdate .= 'd'; break;
1274              case 'D': $fmtdate .= 'm/d/y'; break;
1275              case 'e': $fmtdate .= 'j'; break;
1276              case 'g': $fmtdate .= '\g?'; break; //?
1277              case 'G': $fmtdate .= '\G?'; break; //?
1278              case 'H': $fmtdate .= 'H'; break;
1279              case 'I': $fmtdate .= 'h'; break;
1280              case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd
1281              case 'm': $fmtdate .= 'm'; break;
1282              case 'M': $fmtdate .= 'i'; break;
1283              case 'n': $fmtdate .= "\n"; break;
1284              case 'p': $fmtdate .= 'a'; break;
1285              case 'r': $fmtdate .= 'h:i:s a'; break;
1286              case 'R': $fmtdate .= 'H:i:s'; break;
1287              case 'S': $fmtdate .= 's'; break;
1288              case 't': $fmtdate .= "\t"; break;
1289              case 'T': $fmtdate .= 'H:i:s'; break;
1290              case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based
1291              case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based
1292              case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break;
1293              case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break;
1294              case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based
1295              case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based
1296              case 'y': $fmtdate .= 'y'; break;
1297              case 'Y': $fmtdate .= 'Y'; break;
1298              case 'Z': $fmtdate .= 'T'; break;
1299              }
1300          } else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' ))
1301              $fmtdate .= "\\".$ch;
1302          else
1303              $fmtdate .= $ch;
1304      }
1305      //echo "fmt=",$fmtdate,"<br>";
1306      if ($ts === false) $ts = time();
1307      $ret = adodb_date($fmtdate, $ts, $is_gmt);
1308      return $ret;
1309  }
1310  
1311  
1312  ?>


Généré le : Tue Apr 3 18:50:37 2007 par Balluche grâce à PHPXref 0.7