| [ PHPXref.com ] | [ Generated: Sun Jul 20 20:47:44 2008 ] | [ TUTOS 1.2 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
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 \"$s1\" (date len=".strlen($s1).") 498 \"$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.