[ PHPXref.com ] [ Generated: Sun Jul 20 18:02:19 2008 ] [ Group-Office 2.15-FINAL-7 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

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

   1  <?php
   2  /**

   3  ADOdb Date Library, part of the ADOdb abstraction library

   4  Download: http://php.weblogs.com/adodb_date_time_library

   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  

 245  - 18 July  2005  0.21

 246  - In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat.

 247  - Added support for negative months in adodb_mktime().

 248  

 249  - 24 Feb 2005 0.20

 250  Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date().

 251  

 252  - 21 Dec 2004 0.17

 253  In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false. 

 254  Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro.

 255  

 256  - 17 Nov 2004 0.16

 257  Removed intval typecast in adodb_mktime() for secs, allowing:

 258       adodb_mktime(0,0,0 + 2236672153,1,1,1934);

 259  Suggested by Ryan.

 260  

 261  - 18 July 2004 0.15

 262  All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. 

 263  This brings it more in line with mktime (still not identical).

 264  

 265  - 23 June 2004 0.14

 266  

 267  Allow you to define your own daylights savings function, adodb_daylight_sv.

 268  If the function is defined (somewhere in an include), then you can correct for daylights savings.

 269  

 270  In this example, we apply daylights savings in June or July, adding one hour. This is extremely

 271  unrealistic as it does not take into account time-zone, geographic location, current year.

 272  

 273  function adodb_daylight_sv(&$arr, $is_gmt)

 274  {

 275      if ($is_gmt) return;

 276      $m = $arr['mon'];

 277      if ($m == 6 || $m == 7) $arr['hours'] += 1;

 278  }

 279  

 280  This is only called by adodb_date() and not by adodb_mktime(). 

 281  

 282  The format of $arr is

 283  Array ( 

 284     [seconds] => 0 

 285     [minutes] => 0 

 286     [hours] => 0 

 287     [mday] => 1      # day of month, eg 1st day of the month

 288     [mon] => 2       # month (eg. Feb)

 289     [year] => 2102 

 290     [yday] => 31     # days in current year

 291     [leap] =>        # true if leap year

 292     [ndays] => 28    # no of days in current month

 293     ) 

 294     

 295  

 296  - 28 Apr 2004 0.13

 297  Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov.

 298  

 299  - 20 Mar 2004 0.12

 300  Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32.

 301  

 302  - 26 Oct 2003 0.11

 303  Because of daylight savings problems (some systems apply daylight savings to 

 304  January!!!), changed adodb_get_gmt_diff() to ignore daylight savings.

 305  

 306  - 9 Aug 2003 0.10

 307  Fixed bug with dates after 2038. 

 308  See http://phplens.com/lens/lensforum/msgs.php?id=6980

 309  

 310  - 1 July 2003 0.09

 311  Added support for Q (Quarter).

 312  Added adodb_date2(), which accepts ISO date in 2nd param

 313  

 314  - 3 March 2003 0.08

 315  Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS

 316  if you want PHP to handle negative timestamps between 1901 to 1969.

 317  

 318  - 27 Feb 2003 0.07

 319  All negative numbers handled by adodb now because of RH 7.3+ problems.

 320  See http://bugs.php.net/bug.php?id=20048&edit=2

 321  

 322  - 4 Feb 2003 0.06

 323  Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates

 324  are now correctly handled.

 325  

 326  - 29 Jan 2003 0.05

 327  

 328  Leap year checking differs under Julian calendar (pre 1582). Also

 329  leap year code optimized by checking for most common case first.

 330  

 331  We also handle month overflow correctly in mktime (eg month set to 13).

 332  

 333  Day overflow for less than one month's days is supported.

 334  

 335  - 28 Jan 2003 0.04

 336  

 337  Gregorian correction handled. In PHP5, we might throw an error if 

 338  mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10.

 339  Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582.

 340  

 341  - 27 Jan 2003 0.03

 342  

 343  Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION.

 344  Fixed calculation of days since start of year for <1970. 

 345  

 346  - 27 Jan 2003 0.02

 347  

 348  Changed _adodb_getdate() to inline leap year checking for better performance.

 349  Fixed problem with time-zones west of GMT +0000.

 350  

 351  - 24 Jan 2003 0.01

 352  

 353  First implementation.

 354  */
 355  
 356  
 357  /* Initialization */

 358  
 359  /*

 360      Version Number

 361  */
 362  define('ADODB_DATE_VERSION',0.21);
 363  
 364  /*

 365      This code was originally for windows. But apparently this problem happens 

 366      also with Linux, RH 7.3 and later!

 367      

 368      glibc-2.2.5-34 and greater has been changed to return -1 for dates <

 369      1970.  This used to work.  The problem exists with RedHat 7.3 and 8.0

 370      echo (mktime(0, 0, 0, 1, 1, 1960));  // prints -1

 371      

 372      References:

 373       http://bugs.php.net/bug.php?id=20048&edit=2

 374       http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html

 375  */
 376  
 377  if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
 378  
 379  function adodb_date_test_date($y1,$m,$d=13)
 380  {
 381      $t = adodb_mktime(0,0,0,$m,$d,$y1);
 382      $rez = adodb_date('Y-n-j H:i:s',$t);
 383      if ("$y1-$m-$d 00:00:00" != $rez) {
 384          print "<b>$y1 error, expected=$y1-$m-$d 00:00:00, adodb=$rez</b><br>";
 385          return false;
 386      }
 387      return true;
 388  }
 389  
 390  function adodb_date_test_strftime($fmt)
 391  {
 392      $s1 = strftime($fmt);
 393      $s2 = adodb_strftime($fmt);
 394      
 395      if ($s1 == $s2) return true;
 396      
 397      echo "error for $fmt,  strftime=$s1, $adodb=$s2<br>";
 398      return false;
 399  }
 400  
 401  /**

 402       Test Suite

 403  */
 404  function adodb_date_test()
 405  {
 406      
 407      error_reporting(E_ALL);
 408      print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>";
 409      @set_time_limit(0);
 410      $fail = false;
 411      
 412      // This flag disables calling of PHP native functions, so we can properly test the code

 413      if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
 414      
 415      adodb_date_test_strftime('%Y %m %x %X');
 416      adodb_date_test_strftime("%A %d %B %Y");
 417      adodb_date_test_strftime("%H %M S");
 418      
 419      $t = adodb_mktime(0,0,0);
 420      if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
 421      
 422      $t = adodb_mktime(0,0,0,6,1,2102);
 423      if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
 424      
 425      $t = adodb_mktime(0,0,0,2,1,2102);
 426      if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
 427      
 428      
 429      print "<p>Testing gregorian <=> julian conversion<p>";
 430      $t = adodb_mktime(0,0,0,10,11,1492);
 431      //http://www.holidayorigins.com/html/columbus_day.html - Friday check

 432      if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>';
 433      
 434      $t = adodb_mktime(0,0,0,2,29,1500);
 435      if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>';
 436      
 437      $t = adodb_mktime(0,0,0,2,29,1700);
 438      if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>';
 439      
 440      print  adodb_mktime(0,0,0,10,4,1582).' ';
 441      print adodb_mktime(0,0,0,10,15,1582);
 442      $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582));
 443      if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>";
 444          
 445      print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>";
 446      print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>";
 447      
 448      print "<p>Testing overflow<p>";
 449      
 450      $t = adodb_mktime(0,0,0,3,33,1965);
 451      if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>';
 452      $t = adodb_mktime(0,0,0,4,33,1971);
 453      if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>';
 454      $t = adodb_mktime(0,0,0,1,60,1965);
 455      if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>';
 456      $t = adodb_mktime(0,0,0,12,32,1965);
 457      if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>';
 458      $t = adodb_mktime(0,0,0,12,63,1965);
 459      if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>';
 460      $t = adodb_mktime(0,0,0,13,3,1965);
 461      if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>';
 462      
 463      print "Testing 2-digit => 4-digit year conversion<p>";
 464      if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>";
 465      if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>";
 466      if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>";
 467      if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>";
 468      if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>";
 469      if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
 470      if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
 471      
 472      // Test string formating

 473      print "<p>Testing date formating</p>";
 474      $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';
 475      $s1 = date($fmt,0);
 476      $s2 = adodb_date($fmt,0);
 477      if ($s1 != $s2) {
 478          print " date() 0 failed<br>$s1<br>$s2<br>";
 479      }
 480      flush();
 481      for ($i=100; --$i > 0; ) {
 482  
 483          $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000);
 484          $s1 = date($fmt,$ts);
 485          $s2 = adodb_date($fmt,$ts);
 486          //print "$s1 <br>$s2 <p>";

 487          $pos = strcmp($s1,$s2);
 488  
 489          if (($s1) != ($s2)) {
 490              for ($j=0,$k=strlen($s1); $j < $k; $j++) {
 491                  if ($s1[$j] != $s2[$j]) {
 492                      print substr($s1,$j).' ';
 493                      break;
 494                  }
 495              }
 496              print "<b>Error date(): $ts<br><pre> 
 497  &nbsp; \"$s1\" (date len=".strlen($s1).")
 498  &nbsp; \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>";
 499              $fail = true;
 500          }
 501          
 502          $a1 = getdate($ts);
 503          $a2 = adodb_getdate($ts);
 504          $rez = array_diff($a1,$a2);
 505          if (sizeof($rez)>0) {
 506              print "<b>Error getdate() $ts</b><br>";
 507                  print_r($a1);
 508              print "<br>";
 509                  print_r($a2);
 510              print "<p>";
 511              $fail = true;
 512          }
 513      }
 514      
 515      // Test generation of dates outside 1901-2038

 516      print "<p>Testing random dates between 100 and 4000</p>";
 517      adodb_date_test_date(100,1);
 518      for ($i=100; --$i >= 0;) {
 519          $y1 = 100+rand(0,1970-100);
 520          $m = rand(1,12);
 521          adodb_date_test_date($y1,$m);
 522          
 523          $y1 = 3000-rand(0,3000-1970);
 524          adodb_date_test_date($y1,$m);
 525      }
 526      print '<p>';
 527      $start = 1960+rand(0,10);
 528      $yrs = 12;
 529      $i = 365.25*86400*($start-1970);
 530      $offset = 36000+rand(10000,60000);
 531      $max = 365*$yrs*86400;
 532      $lastyear = 0;
 533      
 534      // we generate a timestamp, convert it to a date, and convert it back to a timestamp

 535      // and check if the roundtrip broke the original timestamp value.

 536      print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
 537      $cnt = 0;
 538      for ($max += $i; $i < $max; $i += $offset) {
 539          $ret = adodb_date('m,d,Y,H,i,s',$i);
 540          $arr = explode(',',$ret);
 541          if ($lastyear != $arr[2]) {
 542              $lastyear = $arr[2];
 543              print " $lastyear ";
 544              flush();
 545          }
 546          $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]);
 547          if ($i != $newi) {
 548              print "Error at $i, adodb_mktime returned $newi ($ret)";
 549              $fail = true;
 550              break;
 551          }
 552          $cnt += 1;
 553      }
 554      echo "Tested $cnt dates<br>";
 555      if (!$fail) print "<p>Passed !</p>";
 556      else print "<p><b>Failed</b> :-(</p>";
 557  }
 558  
 559  /**

 560      Returns day of week, 0 = Sunday,... 6=Saturday. 

 561      Algorithm from PEAR::Date_Calc

 562  */
 563  function adodb_dow($year, $month, $day)
 564  {
 565  /*

 566  Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and 

 567  proclaimed that from that time onwards 3 days would be dropped from the calendar 

 568  every 400 years.

 569  

 570  Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). 

 571  */
 572      if ($year <= 1582) {
 573          if ($year < 1582 || 
 574              ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
 575           else
 576              $greg_correction = 0;
 577      } else
 578          $greg_correction = 0;
 579      
 580      if($month > 2)
 581          $month -= 2;
 582      else {
 583          $month += 10;
 584          $year--;
 585      }
 586      
 587      $day =  floor((13 * $month - 1) / 5) +
 588              $day + ($year % 100) +
 589              floor(($year % 100) / 4) +
 590              floor(($year / 100) / 4) - 2 *
 591              floor($year / 100) + 77 + $greg_correction;
 592      
 593      return $day - 7 * floor($day / 7);
 594  }
 595  
 596  
 597  /**

 598   Checks for leap year, returns true if it is. No 2-digit year check. Also 

 599   handles julian calendar correctly.

 600  */
 601  function _adodb_is_leap_year($year) 
 602  {
 603      if ($year % 4 != 0) return false;
 604      
 605      if ($year % 400 == 0) {
 606          return true;
 607      // if gregorian calendar (>1582), century not-divisible by 400 is not leap

 608      } else if ($year > 1582 && $year % 100 == 0 ) {
 609          return false;
 610      } 
 611      
 612      return true;
 613  }
 614  
 615  
 616  /**

 617   checks for leap year, returns true if it is. Has 2-digit year check

 618  */
 619  function adodb_is_leap_year($year) 
 620  {
 621      return  _adodb_is_leap_year(adodb_year_digit_check($year));
 622  }
 623  
 624  /**

 625      Fix 2-digit years. Works for any century.

 626       Assumes that if 2-digit is more than 30 years in future, then previous century.

 627  */
 628  function adodb_year_digit_check($y) 
 629  {
 630      if ($y < 100) {
 631      
 632          $yr = (integer) date("Y");
 633          $century = (integer) ($yr /100);
 634          
 635          if ($yr%100 > 50) {
 636              $c1 = $century + 1;
 637              $c0 = $century;
 638          } else {
 639              $c1 = $century;
 640              $c0 = $century - 1;
 641          }
 642          $c1 *= 100;
 643          // if 2-digit year is less than 30 years in future, set it to this century

 644          // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.

 645          if (($y + $c1) < $yr+30) $y = $y + $c1;
 646          else $y = $y + $c0*100;
 647      }
 648      return $y;
 649  }
 650  
 651  /**

 652   get local time zone offset from GMT

 653  */
 654  function adodb_get_gmt_diff() 
 655  {
 656  static $TZ;
 657      if (isset($TZ)) return $TZ;
 658      
 659      $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0);
 660      return $TZ;
 661  }
 662  
 663  /**

 664      Returns an array with date info.

 665  */
 666  function adodb_getdate($d=false,$fast=false)
 667  {
 668      if ($d === false) return getdate();
 669      if (!defined('ADODB_TEST_DATES')) {
 670          if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 671              if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
 672                  return @getdate($d);
 673          }
 674      }
 675      return _adodb_getdate($d);
 676  }
 677  
 678  /*

 679  // generate $YRS table for _adodb_getdate()

 680  function adodb_date_gentable($out=true)

 681  {

 682  

 683      for ($i=1970; $i >= 1600; $i-=10) {

 684          $s = adodb_gmmktime(0,0,0,1,1,$i);

 685          echo "$i => $s,<br>";    

 686      }

 687  }

 688  adodb_date_gentable();

 689  

 690  for ($i=1970; $i > 1500; $i--) {

 691  

 692  echo "<hr>$i ";

 693      adodb_date_test_date($i,1,1);

 694  }

 695  

 696  */
 697  
 698  /**

 699      Low-level function that returns the getdate() array. We have a special

 700      $fast flag, which if set to true, will return fewer array values,

 701      and is much faster as it does not calculate dow, etc.

 702  */
 703  function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
 704  {
 705  static $YRS;
 706  
 707      $d =  $origd - ($is_gmt ? 0 : adodb_get_gmt_diff());
 708      
 709      $_day_power = 86400;
 710      $_hour_power = 3600;
 711      $_min_power = 60;
 712      
 713      if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction 

 714      
 715      $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
 716      $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
 717      
 718      $d366 = $_day_power * 366;
 719      $d365 = $_day_power * 365;
 720      
 721      if ($d < 0) {
 722          
 723          if (empty($YRS)) $YRS = array(
 724              1970 => 0,
 725              1960 => -315619200,
 726              1950 => -631152000,
 727              1940 => -946771200,
 728              1930 => -1262304000,
 729              1920 => -1577923200,
 730              1910 => -1893456000,
 731              1900 => -2208988800,
 732              1890 => -2524521600,
 733              1880 => -2840140800,
 734              1870 => -3155673600,
 735              1860 => -3471292800,
 736              1850 => -3786825600,
 737              1840 => -4102444800,
 738              1830 => -4417977600,
 739              1820 => -4733596800,
 740              1810 => -5049129600,
 741              1800 => -5364662400,
 742              1790 => -5680195200,
 743              1780 => -5995814400,
 744              1770 => -6311347200,
 745              1760 => -6626966400,
 746              1750 => -6942499200,
 747              1740 => -7258118400,
 748              1730 => -7573651200,
 749              1720 => -7889270400,
 750              1710 => -8204803200,
 751              1700 => -8520336000,
 752              1690 => -8835868800,
 753              1680 => -9151488000,
 754              1670 => -9467020800,
 755              1660 => -9782640000,
 756              1650 => -10098172800,
 757              1640 => -10413792000,
 758              1630 => -10729324800,
 759              1620 => -11044944000,
 760              1610 => -11360476800,
 761              1600 => -11676096000);
 762  
 763          if ($is_gmt) $origd = $d;
 764          // The valid range of a 32bit signed timestamp is typically from 

 765          // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT

 766          //

 767          
 768          # old algorithm iterates through all years. new algorithm does it in

 769          # 10 year blocks

 770          
 771          /*

 772          # old algo

 773          for ($a = 1970 ; --$a >= 0;) {

 774              $lastd = $d;

 775              

 776              if ($leaf = _adodb_is_leap_year($a)) $d += $d366;

 777              else $d += $d365;

 778              

 779              if ($d >= 0) {

 780                  $year = $a;

 781                  break;

 782              }

 783          }

 784          */
 785          
 786          $lastsecs = 0;
 787          $lastyear = 1970;
 788          foreach($YRS as $year => $secs) {
 789              if ($d >= $secs) {
 790                  $a = $lastyear;
 791                  break;
 792              }
 793              $lastsecs = $secs;
 794              $lastyear = $year;
 795          }
 796          
 797          $d -= $lastsecs;
 798          if (!isset($a)) $a = $lastyear;
 799          
 800          //echo ' yr=',$a,' ', $d,'.';

 801          
 802          for (; --$a >= 0;) {
 803              $lastd = $d;
 804              
 805              if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
 806              else $d += $d365;
 807              
 808              if ($d >= 0) {
 809                  $year = $a;
 810                  break;
 811              }
 812          }
 813          /**/

 814          
 815          $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
 816          
 817          $d = $lastd;
 818          $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
 819          for ($a = 13 ; --$a > 0;) {
 820              $lastd = $d;
 821              $d += $mtab[$a] * $_day_power;
 822              if ($d >= 0) {
 823                  $month = $a;
 824                  $ndays = $mtab[$a];
 825                  break;
 826              }
 827          }
 828          
 829          $d = $lastd;
 830          $day = $ndays + ceil(($d+1) / ($_day_power));
 831  
 832          $d += ($ndays - $day+1)* $_day_power;
 833          $hour = floor($d/$_hour_power);
 834      
 835      } else {
 836          for ($a = 1970 ;; $a++) {
 837              $lastd = $d;
 838              
 839              if ($leaf = _adodb_is_leap_year($a)) $d -= $d366;
 840              else $d -= $d365;
 841              if ($d < 0) {
 842                  $year = $a;
 843                  break;
 844              }
 845          }
 846          $secsInYear = $lastd;
 847          $d = $lastd;
 848          $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
 849          for ($a = 1 ; $a <= 12; $a++) {
 850              $lastd = $d;
 851              $d -= $mtab[$a] * $_day_power;
 852              if ($d < 0) {
 853                  $month = $a;
 854                  $ndays = $mtab[$a];
 855                  break;
 856              }
 857          }
 858          $d = $lastd;
 859          $day = ceil(($d+1) / $_day_power);
 860          $d = $d - ($day-1) * $_day_power;
 861          $hour = floor($d /$_hour_power);
 862      }
 863      
 864      $d -= $hour * $_hour_power;
 865      $min = floor($d/$_min_power);
 866      $secs = $d - $min * $_min_power;
 867      if ($fast) {
 868          return array(
 869          'seconds' => $secs,
 870          'minutes' => $min,
 871          'hours' => $hour,
 872          'mday' => $day,
 873          'mon' => $month,
 874          'year' => $year,
 875          'yday' => floor($secsInYear/$_day_power),
 876          'leap' => $leaf,
 877          'ndays' => $ndays
 878          );
 879      }
 880      
 881      
 882      $dow = adodb_dow($year,$month,$day);
 883  
 884      return array(
 885          'seconds' => $secs,
 886          'minutes' => $min,
 887          'hours' => $hour,
 888          'mday' => $day,
 889          'wday' => $dow,
 890          'mon' => $month,
 891          'year' => $year,
 892          'yday' => floor($secsInYear/$_day_power),
 893          'weekday' => gmdate('l',$_day_power*(3+$dow)),
 894          'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
 895          0 => $origd
 896      );
 897  }
 898  
 899  function adodb_gmdate($fmt,$d=false)
 900  {
 901      return adodb_date($fmt,$d,true);
 902  }
 903  
 904  // accepts unix timestamp and iso date format in $d

 905  function adodb_date2($fmt, $d=false, $is_gmt=false)
 906  {
 907      if ($d !== false) {
 908          if (!preg_match( 
 909              "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 
 910              ($d), $rr)) return adodb_date($fmt,false,$is_gmt);
 911  
 912          if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
 913      
 914          // h-m-s-MM-DD-YY

 915          if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
 916          else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
 917      }
 918      
 919      return adodb_date($fmt,$d,$is_gmt);
 920  }
 921  
 922  
 923  /**

 924      Return formatted date based on timestamp $d

 925  */
 926  function adodb_date($fmt,$d=false,$is_gmt=false)
 927  {
 928  static $daylight;
 929  
 930      if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
 931      if (!defined('ADODB_TEST_DATES')) {
 932          if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
 933              if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
 934                  return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
 935  
 936          }
 937      }
 938      $_day_power = 86400;
 939      
 940      $arr = _adodb_getdate($d,true,$is_gmt);
 941      
 942      if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
 943      if ($daylight) adodb_daylight_sv($arr, $is_gmt);
 944      
 945      $year = $arr['year'];
 946      $month = $arr['mon'];
 947      $day = $arr['mday'];
 948      $hour = $arr['hours'];
 949      $min = $arr['minutes'];
 950      $secs = $arr['seconds'];
 951      
 952      $max = strlen($fmt);
 953      $dates = '';
 954      
 955      /*

 956          at this point, we have the following integer vars to manipulate:

 957          $year, $month, $day, $hour, $min, $secs

 958      */
 959      for ($i=0; $i < $max; $i++) {
 960          switch($fmt[$i]) {
 961          case 'T': $dates .= date('T');break;
 962          // YEAR

 963          case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
 964          case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
 965          
 966              // 4.3.11 uses '04 Jun 2004'

 967              // 4.3.8 uses  ' 4 Jun 2004'

 968              $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '        
 969                  . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
 970              
 971              if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; 
 972              
 973              if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
 974              
 975              if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
 976              
 977              $gmt = adodb_get_gmt_diff();
 978              $dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
 979                  
 980          case 'Y': $dates .= $year; break;
 981          case 'y': $dates .= substr($year,strlen($year)-2,2); break;
 982          // MONTH

 983          case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
 984          case 'Q': $dates .= ($month+3)>>2; break;
 985          case 'n': $dates .= $month; break;
 986          case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
 987          case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
 988          // DAY

 989          case 't': $dates .= $arr['ndays']; break;
 990          case 'z': $dates .= $arr['yday']; break;
 991          case 'w': $dates .= adodb_dow($year,$month,$day); break;
 992          case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
 993          case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
 994          case 'j': $dates .= $day; break;
 995          case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
 996          case 'S': 
 997              $d10 = $day % 10;
 998              if ($d10 == 1) $dates .= 'st';
 999              else if ($d10 == 2 && $day != 12) $dates .= 'nd';
1000              else if ($d10 == 3) $dates .= 'rd';
1001              else $dates .= 'th';
1002              break;
1003              
1004          // HOUR

1005          case 'Z':
1006              $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break;
1007          case 'O': 
1008              $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff();
1009              $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
1010              
1011          case 'H': 
1012              if ($hour < 10) $dates .= '0'.$hour; 
1013              else $dates .= $hour; 
1014              break;
1015          case 'h': 
1016              if ($hour > 12) $hh = $hour - 12; 
1017              else {
1018                  if ($hour == 0) $hh = '12'; 
1019                  else $hh = $hour;
1020              }
1021              
1022              if ($hh < 10) $dates .= '0'.$hh;
1023              else $dates .= $hh;
1024              break;
1025              
1026          case 'G': 
1027              $dates .= $hour;
1028              break;
1029              
1030          case 'g':
1031              if ($hour > 12) $hh = $hour - 12; 
1032              else {
1033                  if ($hour == 0) $hh = '12'; 
1034                  else $hh = $hour; 
1035              }
1036              $dates .= $hh;
1037              break;
1038          // MINUTES

1039          case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
1040          // SECONDS

1041          case 'U': $dates .= $d; break;
1042          case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
1043          // AM/PM

1044          // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM

1045          case 'a':
1046              if ($hour>=12) $dates .= 'pm';
1047              else $dates .= 'am';
1048              break;
1049          case 'A':
1050              if ($hour>=12) $dates .= 'PM';
1051              else $dates .= 'AM';
1052              break;
1053          default:
1054              $dates .= $fmt[$i]; break;
1055          // ESCAPE

1056          case "\\": 
1057              $i++;
1058              if ($i < $max) $dates .= $fmt[$i];
1059              break;
1060          }
1061      }
1062      return $dates;
1063  }
1064  
1065  /**

1066      Returns a timestamp given a GMT/UTC time. 

1067      Note that $is_dst is not implemented and is ignored.

1068  */
1069  function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
1070  {
1071      return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
1072  }
1073  
1074  /**

1075      Return a timestamp given a local time. Originally by jackbbs.

1076      Note that $is_dst is not implemented and is ignored.

1077      

1078      Not a very fast algorithm - O(n) operation. Could be optimized to O(1).

1079  */
1080  function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false) 
1081  {
1082      if (!defined('ADODB_TEST_DATES')) {
1083  
1084          if ($mon === false) {
1085              return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
1086          }
1087          
1088          // for windows, we don't check 1970 because with timezone differences, 

1089          // 1 Jan 1970 could generate negative timestamp, which is illegal

1090          if (1971 < $year && $year < 2038
1091              || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
1092              ) {
1093                  return $is_gmt ?
1094                      @gmmktime($hr,$min,$sec,$mon,$day,$year):
1095                      @mktime($hr,$min,$sec,$mon,$day,$year);
1096              }
1097      }
1098      
1099      $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff();
1100  
1101      /*

1102      # disabled because some people place large values in $sec.

1103      # however we need it for $mon because we use an array...

1104      $hr = intval($hr);

1105      $min = intval($min);

1106      $sec = intval($sec);

1107      */
1108      $mon = intval($mon);
1109      $day = intval($day);
1110      $year = intval($year);
1111      
1112      
1113      $year = adodb_year_digit_check($year);
1114  
1115      if ($mon > 12) {
1116          $y = floor($mon / 12);
1117          $year += $y;
1118          $mon -= $y*12;
1119      } else if ($mon < 1) {
1120          $y = ceil((1-$mon) / 12);
1121          $year -= $y;
1122          $mon += $y*12;
1123      }
1124      
1125      $_day_power = 86400;
1126      $_hour_power = 3600;
1127      $_min_power = 60;
1128      
1129      $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
1130      $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
1131      
1132      $_total_date = 0;
1133      if ($year >= 1970) {
1134          for ($a = 1970 ; $a <= $year; $a++) {
1135              $leaf = _adodb_is_leap_year($a);
1136              if ($leaf == true) {
1137                  $loop_table = $_month_table_leaf;
1138                  $_add_date = 366;
1139              } else {
1140                  $loop_table = $_month_table_normal;
1141                  $_add_date = 365;
1142              }
1143              if ($a < $year) { 
1144                  $_total_date += $_add_date;
1145              } else {
1146                  for($b=1;$b<$mon;$b++) {
1147                      $_total_date += $loop_table[$b];
1148                  }
1149              }
1150          }
1151          $_total_date +=$day-1;
1152          $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
1153      
1154      } else {
1155          for ($a = 1969 ; $a >= $year; $a--) {
1156              $leaf = _adodb_is_leap_year($a);
1157              if ($leaf == true) {
1158                  $loop_table = $_month_table_leaf;
1159                  $_add_date = 366;
1160              } else {
1161                  $loop_table = $_month_table_normal;
1162                  $_add_date = 365;
1163              }
1164              if ($a > $year) { $_total_date += $_add_date;
1165              } else {
1166                  for($b=12;$b>$mon;$b--) {
1167                      $_total_date += $loop_table[$b];
1168                  }
1169              }
1170          }
1171          $_total_date += $loop_table[$mon] - $day;
1172          
1173          $_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
1174          $_day_time = $_day_power - $_day_time;
1175          $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
1176          if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction

1177          else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.

1178      } 
1179      //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;

1180      return $ret;
1181  }
1182  
1183  function adodb_gmstrftime($fmt, $ts=false)
1184  {
1185      return adodb_strftime($fmt,$ts,true);
1186  }
1187  
1188  // hack - convert to adodb_date

1189  function adodb_strftime($fmt, $ts=false,$is_gmt=false)
1190  {
1191  global $ADODB_DATE_LOCALE;
1192  
1193      if (!defined('ADODB_TEST_DATES')) {
1194          if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
1195              if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer
1196                  return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts);
1197  
1198          }
1199      }
1200      
1201      if (empty($ADODB_DATE_LOCALE)) {
1202          $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am

1203          $sep = substr($tstr,2,1);
1204          $hasAM = strrpos($tstr,'M') !== false;
1205          
1206          $ADODB_DATE_LOCALE = array();
1207          $ADODB_DATE_LOCALE[] =  strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y';    
1208          $ADODB_DATE_LOCALE[]  = ($hasAM) ? 'h:i:s a' : 'H:i:s';
1209              
1210      }
1211      $inpct = false;
1212      $fmtdate = '';
1213      for ($i=0,$max = strlen($fmt); $i < $max; $i++) {
1214          $ch = $fmt[$i];
1215          if ($ch == '%') {
1216              if ($inpct) {
1217                  $fmtdate .= '%';
1218                  $inpct = false;
1219              } else
1220                  $inpct = true;
1221          } else if ($inpct) {
1222          
1223              $inpct = false;
1224              switch($ch) {
1225              case '0':
1226              case '1':
1227              case '2':
1228              case '3':
1229              case '4':
1230              case '5':
1231              case '6':
1232              case '7':
1233              case '8':
1234              case '9':
1235              case 'E':
1236              case 'O':
1237                  /* ignore format modifiers */

1238                  $inpct = true; 
1239                  break;
1240                  
1241              case 'a': $fmtdate .= 'D'; break;
1242              case 'A': $fmtdate .= 'l'; break;
1243              case 'h':
1244              case 'b': $fmtdate .= 'M'; break;
1245              case 'B': $fmtdate .= 'F'; break;
1246              case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break;
1247              case 'C': $fmtdate .= '\C?'; break; // century

1248              case 'd': $fmtdate .= 'd'; break;
1249              case 'D': $fmtdate .= 'm/d/y'; break;
1250              case 'e': $fmtdate .= 'j'; break;
1251              case 'g': $fmtdate .= '\g?'; break; //?

1252              case 'G': $fmtdate .= '\G?'; break; //?

1253              case 'H': $fmtdate .= 'H'; break;
1254              case 'I': $fmtdate .= 'h'; break;
1255              case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd

1256              case 'm': $fmtdate .= 'm'; break;
1257              case 'M': $fmtdate .= 'i'; break;
1258              case 'n': $fmtdate .= "\n"; break;
1259              case 'p': $fmtdate .= 'a'; break;
1260              case 'r': $fmtdate .= 'h:i:s a'; break;
1261              case 'R': $fmtdate .= 'H:i:s'; break;
1262              case 'S': $fmtdate .= 's'; break;
1263              case 't': $fmtdate .= "\t"; break;
1264              case 'T': $fmtdate .= 'H:i:s'; break;
1265              case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-basde

1266              case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based

1267              case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break;
1268              case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break;
1269              case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-basde

1270              case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based

1271              case 'y': $fmtdate .= 'y'; break;
1272              case 'Y': $fmtdate .= 'Y'; break;
1273              case 'Z': $fmtdate .= 'T'; break;
1274              }
1275          } else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' ))
1276              $fmtdate .= "\\".$ch;
1277          else
1278              $fmtdate .= $ch;
1279      }
1280      //echo "fmt=",$fmtdate,"<br>";

1281      if ($ts === false) $ts = time();
1282      $ret = adodb_date($fmtdate, $ts, $is_gmt);
1283      return $ret;
1284  }
1285  
1286  
1287  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]