[ Index ]
 

Code source de vtiger CRM 5.0.2

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

title

Body

[fermer]

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


Généré le : Sun Feb 25 10:22:19 2007 par Balluche grâce à PHPXref 0.7