Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/adodb/adodb-time.inc.php
Go to the documentation of this file.
00001 <?php
00390 /* Initialization */
00391 
00392 /*
00393         Version Number
00394 */
00395 define('ADODB_DATE_VERSION',0.35);
00396 
00397 $ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
00398 
00399 /*
00400         This code was originally for windows. But apparently this problem happens 
00401         also with Linux, RH 7.3 and later!
00402         
00403         glibc-2.2.5-34 and greater has been changed to return -1 for dates <
00404         1970.  This used to work.  The problem exists with RedHat 7.3 and 8.0
00405         echo (mktime(0, 0, 0, 1, 1, 1960));  // prints -1
00406         
00407         References:
00408          http://bugs.php.net/bug.php?id=20048&edit=2
00409          http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html
00410 */
00411 
00412 if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
00413 
00414 function adodb_date_test_date($y1,$m,$d=13)
00415 {
00416         $h = round(rand()% 24);
00417         $t = adodb_mktime($h,0,0,$m,$d,$y1);
00418         $rez = adodb_date('Y-n-j H:i:s',$t);
00419         if ($h == 0) $h = '00';
00420         else if ($h < 10) $h = '0'.$h;
00421         if ("$y1-$m-$d $h:00:00" != $rez) {
00422                 print "<b>$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez</b><br>";
00423                 return false;
00424         }
00425         return true;
00426 }
00427 
00428 function adodb_date_test_strftime($fmt)
00429 {
00430         $s1 = strftime($fmt);
00431         $s2 = adodb_strftime($fmt);
00432         
00433         if ($s1 == $s2) return true;
00434         
00435         echo "error for $fmt,  strftime=$s1, adodb=$s2<br>";
00436         return false;
00437 }
00438 
00442 function adodb_date_test()
00443 {
00444         
00445         for ($m=-24; $m<=24; $m++)
00446                 echo "$m :",adodb_date('d-m-Y',adodb_mktime(0,0,0,1+$m,20,2040)),"<br>";
00447         
00448         error_reporting(E_ALL);
00449         print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>";
00450         @set_time_limit(0);
00451         $fail = false;
00452         
00453         // This flag disables calling of PHP native functions, so we can properly test the code
00454         if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
00455         
00456         $t = time();
00457         
00458         
00459         $fmt = 'Y-m-d H:i:s';
00460         echo '<pre>';
00461         echo 'adodb: ',adodb_date($fmt,$t),'<br>';
00462         echo 'php  : ',date($fmt,$t),'<br>';
00463         echo '</pre>';
00464         
00465         adodb_date_test_strftime('%Y %m %x %X');
00466         adodb_date_test_strftime("%A %d %B %Y");
00467         adodb_date_test_strftime("%H %M S");
00468         
00469         $t = adodb_mktime(0,0,0);
00470         if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
00471         
00472         $t = adodb_mktime(0,0,0,6,1,2102);
00473         if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
00474         
00475         $t = adodb_mktime(0,0,0,2,1,2102);
00476         if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
00477         
00478         
00479         print "<p>Testing gregorian <=> julian conversion<p>";
00480         $t = adodb_mktime(0,0,0,10,11,1492);
00481         //http://www.holidayorigins.com/html/columbus_day.html - Friday check
00482         if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>';
00483         
00484         $t = adodb_mktime(0,0,0,2,29,1500);
00485         if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>';
00486         
00487         $t = adodb_mktime(0,0,0,2,29,1700);
00488         if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>';
00489         
00490         print  adodb_mktime(0,0,0,10,4,1582).' ';
00491         print adodb_mktime(0,0,0,10,15,1582);
00492         $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582));
00493         if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>";
00494                 
00495         print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>";
00496         print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>";
00497         
00498         print "<p>Testing overflow<p>";
00499         
00500         $t = adodb_mktime(0,0,0,3,33,1965);
00501         if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>';
00502         $t = adodb_mktime(0,0,0,4,33,1971);
00503         if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>';
00504         $t = adodb_mktime(0,0,0,1,60,1965);
00505         if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>';
00506         $t = adodb_mktime(0,0,0,12,32,1965);
00507         if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>';
00508         $t = adodb_mktime(0,0,0,12,63,1965);
00509         if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>';
00510         $t = adodb_mktime(0,0,0,13,3,1965);
00511         if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>';
00512         
00513         print "Testing 2-digit => 4-digit year conversion<p>";
00514         if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>";
00515         if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>";
00516         if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>";
00517         if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>";
00518         if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>";
00519         if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
00520         if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
00521         
00522         // Test string formating
00523         print "<p>Testing date formating</p>";
00524         
00525         $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';
00526         $s1 = date($fmt,0);
00527         $s2 = adodb_date($fmt,0);
00528         if ($s1 != $s2) {
00529                 print " date() 0 failed<br>$s1<br>$s2<br>";
00530         }
00531         flush();
00532         for ($i=100; --$i > 0; ) {
00533 
00534                 $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000);
00535                 $s1 = date($fmt,$ts);
00536                 $s2 = adodb_date($fmt,$ts);
00537                 //print "$s1 <br>$s2 <p>";
00538                 $pos = strcmp($s1,$s2);
00539 
00540                 if (($s1) != ($s2)) {
00541                         for ($j=0,$k=strlen($s1); $j < $k; $j++) {
00542                                 if ($s1[$j] != $s2[$j]) {
00543                                         print substr($s1,$j).' ';
00544                                         break;
00545                                 }
00546                         }
00547                         print "<b>Error date(): $ts<br><pre> 
00548 &nbsp; \"$s1\" (date len=".strlen($s1).")
00549 &nbsp; \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>";
00550                         $fail = true;
00551                 }
00552                 
00553                 $a1 = getdate($ts);
00554                 $a2 = adodb_getdate($ts);
00555                 $rez = array_diff($a1,$a2);
00556                 if (sizeof($rez)>0) {
00557                         print "<b>Error getdate() $ts</b><br>";
00558                                 print_r($a1);
00559                         print "<br>";
00560                                 print_r($a2);
00561                         print "<p>";
00562                         $fail = true;
00563                 }
00564         }
00565         
00566         // Test generation of dates outside 1901-2038
00567         print "<p>Testing random dates between 100 and 4000</p>";
00568         adodb_date_test_date(100,1);
00569         for ($i=100; --$i >= 0;) {
00570                 $y1 = 100+rand(0,1970-100);
00571                 $m = rand(1,12);
00572                 adodb_date_test_date($y1,$m);
00573                 
00574                 $y1 = 3000-rand(0,3000-1970);
00575                 adodb_date_test_date($y1,$m);
00576         }
00577         print '<p>';
00578         $start = 1960+rand(0,10);
00579         $yrs = 12;
00580         $i = 365.25*86400*($start-1970);
00581         $offset = 36000+rand(10000,60000);
00582         $max = 365*$yrs*86400;
00583         $lastyear = 0;
00584         
00585         // we generate a timestamp, convert it to a date, and convert it back to a timestamp
00586         // and check if the roundtrip broke the original timestamp value.
00587         print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
00588         $cnt = 0;
00589         for ($max += $i; $i < $max; $i += $offset) {
00590                 $ret = adodb_date('m,d,Y,H,i,s',$i);
00591                 $arr = explode(',',$ret);
00592                 if ($lastyear != $arr[2]) {
00593                         $lastyear = $arr[2];
00594                         print " $lastyear ";
00595                         flush();
00596                 }
00597                 $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]);
00598                 if ($i != $newi) {
00599                         print "Error at $i, adodb_mktime returned $newi ($ret)";
00600                         $fail = true;
00601                         break;
00602                 }
00603                 $cnt += 1;
00604         }
00605         echo "Tested $cnt dates<br>";
00606         if (!$fail) print "<p>Passed !</p>";
00607         else print "<p><b>Failed</b> :-(</p>";
00608 }
00609 
00614 function adodb_dow($year, $month, $day)
00615 {
00616 /*
00617 Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and 
00618 proclaimed that from that time onwards 3 days would be dropped from the calendar 
00619 every 400 years.
00620 
00621 Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). 
00622 */
00623         if ($year <= 1582) {
00624                 if ($year < 1582 || 
00625                         ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
00626                  else
00627                         $greg_correction = 0;
00628         } else
00629                 $greg_correction = 0;
00630         
00631         if($month > 2)
00632             $month -= 2;
00633         else {
00634             $month += 10;
00635             $year--;
00636         }
00637         
00638         $day =  floor((13 * $month - 1) / 5) +
00639                 $day + ($year % 100) +
00640                 floor(($year % 100) / 4) +
00641                 floor(($year / 100) / 4) - 2 *
00642                 floor($year / 100) + 77 + $greg_correction;
00643         
00644         return $day - 7 * floor($day / 7);
00645 }
00646 
00647 
00652 function _adodb_is_leap_year($year) 
00653 {
00654         if ($year % 4 != 0) return false;
00655         
00656         if ($year % 400 == 0) {
00657                 return true;
00658         // if gregorian calendar (>1582), century not-divisible by 400 is not leap
00659         } else if ($year > 1582 && $year % 100 == 0 ) {
00660                 return false;
00661         } 
00662         
00663         return true;
00664 }
00665 
00666 
00670 function adodb_is_leap_year($year) 
00671 {
00672         return  _adodb_is_leap_year(adodb_year_digit_check($year));
00673 }
00674 
00679 function adodb_year_digit_check($y) 
00680 {
00681         if ($y < 100) {
00682         
00683                 $yr = (integer) date("Y");
00684                 $century = (integer) ($yr /100);
00685                 
00686                 if ($yr%100 > 50) {
00687                         $c1 = $century + 1;
00688                         $c0 = $century;
00689                 } else {
00690                         $c1 = $century;
00691                         $c0 = $century - 1;
00692                 }
00693                 $c1 *= 100;
00694                 // if 2-digit year is less than 30 years in future, set it to this century
00695                 // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
00696                 if (($y + $c1) < $yr+30) $y = $y + $c1;
00697                 else $y = $y + $c0*100;
00698         }
00699         return $y;
00700 }
00701 
00702 function adodb_get_gmt_diff_ts($ts) 
00703 {
00704         if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) {
00705                 $arr = getdate($ts);
00706                 $y = $arr['year'];
00707                 $m = $arr['mon'];
00708                 $d = $arr['mday'];
00709                 return adodb_get_gmt_diff($y,$m,$d);    
00710         } else {
00711                 return adodb_get_gmt_diff(false,false,false);
00712         }
00713         
00714 }
00715 
00719 function adodb_get_gmt_diff($y,$m,$d) 
00720 {
00721 static $TZ,$tzo;
00722 global $ADODB_DATETIME_CLASS;
00723 
00724         if (!defined('ADODB_TEST_DATES')) $y = false;
00725         else if ($y < 1970 || $y >= 2038) $y = false;
00726 
00727         if ($ADODB_DATETIME_CLASS && $y !== false) {
00728                 $dt = new DateTime();
00729                 $dt->setISODate($y,$m,$d);
00730                 if (empty($tzo)) {
00731                         $tzo = new DateTimeZone(date_default_timezone_get());
00732                 #       $tzt = timezone_transitions_get( $tzo );
00733                 }
00734                 return -$tzo->getOffset($dt);
00735         } else {
00736                 if (isset($TZ)) return $TZ;
00737                 $y = date('Y');
00738                 /*
00739                 if (function_exists('date_default_timezone_get') && function_exists('timezone_offset_get')) {
00740                         $tzonename = date_default_timezone_get();
00741                         if ($tzonename) {
00742                                 $tobj = new DateTimeZone($tzonename);
00743                                 $TZ = -timezone_offset_get($tobj,new DateTime("now",$tzo));
00744                         }
00745                 } 
00746                 */
00747                 if (empty($TZ)) $TZ = mktime(0,0,0,12,2,$y) - gmmktime(0,0,0,12,2,$y);
00748         }
00749         return $TZ;
00750 }
00751 
00755 function adodb_getdate($d=false,$fast=false)
00756 {
00757         if ($d === false) return getdate();
00758         if (!defined('ADODB_TEST_DATES')) {
00759                 if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
00760                         if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
00761                                 return @getdate($d);
00762                 }
00763         }
00764         return _adodb_getdate($d);
00765 }
00766 
00767 /*
00768 // generate $YRS table for _adodb_getdate()
00769 function adodb_date_gentable($out=true)
00770 {
00771 
00772         for ($i=1970; $i >= 1600; $i-=10) {
00773                 $s = adodb_gmmktime(0,0,0,1,1,$i);
00774                 echo "$i => $s,<br>";   
00775         }
00776 }
00777 adodb_date_gentable();
00778 
00779 for ($i=1970; $i > 1500; $i--) {
00780 
00781 echo "<hr />$i ";
00782         adodb_date_test_date($i,1,1);
00783 }
00784 
00785 */
00786 
00787 
00788 $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
00789 $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
00790         
00791 function adodb_validdate($y,$m,$d)
00792 {
00793 global $_month_table_normal,$_month_table_leaf;
00794 
00795         if (_adodb_is_leap_year($y)) $marr = $_month_table_leaf;
00796         else $marr = $_month_table_normal;
00797         
00798         if ($m > 12 || $m < 1) return false;
00799         
00800         if ($d > 31 || $d < 1) return false;
00801         
00802         if ($marr[$m] < $d) return false;
00803         
00804         if ($y < 1000 && $y > 3000) return false;
00805         
00806         return true;
00807 }
00808 
00814 function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
00815 {
00816 static $YRS;
00817 global $_month_table_normal,$_month_table_leaf;
00818 
00819         $d =  $origd - ($is_gmt ? 0 : adodb_get_gmt_diff_ts($origd));
00820         $_day_power = 86400;
00821         $_hour_power = 3600;
00822         $_min_power = 60;
00823         
00824         if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction 
00825         
00826         $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
00827         $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
00828         
00829         $d366 = $_day_power * 366;
00830         $d365 = $_day_power * 365;
00831         
00832         if ($d < 0) {
00833                 
00834                 if (empty($YRS)) $YRS = array(
00835                         1970 => 0,
00836                         1960 => -315619200,
00837                         1950 => -631152000,
00838                         1940 => -946771200,
00839                         1930 => -1262304000,
00840                         1920 => -1577923200,
00841                         1910 => -1893456000,
00842                         1900 => -2208988800,
00843                         1890 => -2524521600,
00844                         1880 => -2840140800,
00845                         1870 => -3155673600,
00846                         1860 => -3471292800,
00847                         1850 => -3786825600,
00848                         1840 => -4102444800,
00849                         1830 => -4417977600,
00850                         1820 => -4733596800,
00851                         1810 => -5049129600,
00852                         1800 => -5364662400,
00853                         1790 => -5680195200,
00854                         1780 => -5995814400,
00855                         1770 => -6311347200,
00856                         1760 => -6626966400,
00857                         1750 => -6942499200,
00858                         1740 => -7258118400,
00859                         1730 => -7573651200,
00860                         1720 => -7889270400,
00861                         1710 => -8204803200,
00862                         1700 => -8520336000,
00863                         1690 => -8835868800,
00864                         1680 => -9151488000,
00865                         1670 => -9467020800,
00866                         1660 => -9782640000,
00867                         1650 => -10098172800,
00868                         1640 => -10413792000,
00869                         1630 => -10729324800,
00870                         1620 => -11044944000,
00871                         1610 => -11360476800,
00872                         1600 => -11676096000);
00873 
00874                 if ($is_gmt) $origd = $d;
00875                 // The valid range of a 32bit signed timestamp is typically from 
00876                 // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
00877                 //
00878                 
00879                 # old algorithm iterates through all years. new algorithm does it in
00880                 # 10 year blocks
00881                 
00882                 /*
00883                 # old algo
00884                 for ($a = 1970 ; --$a >= 0;) {
00885                         $lastd = $d;
00886                         
00887                         if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
00888                         else $d += $d365;
00889                         
00890                         if ($d >= 0) {
00891                                 $year = $a;
00892                                 break;
00893                         }
00894                 }
00895                 */
00896                 
00897                 $lastsecs = 0;
00898                 $lastyear = 1970;
00899                 foreach($YRS as $year => $secs) {
00900                         if ($d >= $secs) {
00901                                 $a = $lastyear;
00902                                 break;
00903                         }
00904                         $lastsecs = $secs;
00905                         $lastyear = $year;
00906                 }
00907                 
00908                 $d -= $lastsecs;
00909                 if (!isset($a)) $a = $lastyear;
00910                 
00911                 //echo ' yr=',$a,' ', $d,'.';
00912                 
00913                 for (; --$a >= 0;) {
00914                         $lastd = $d;
00915                         
00916                         if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
00917                         else $d += $d365;
00918                         
00919                         if ($d >= 0) {
00920                                 $year = $a;
00921                                 break;
00922                         }
00923                 }
00924                 
00925                 
00926                 $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
00927                 
00928                 $d = $lastd;
00929                 $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
00930                 for ($a = 13 ; --$a > 0;) {
00931                         $lastd = $d;
00932                         $d += $mtab[$a] * $_day_power;
00933                         if ($d >= 0) {
00934                                 $month = $a;
00935                                 $ndays = $mtab[$a];
00936                                 break;
00937                         }
00938                 }
00939                 
00940                 $d = $lastd;
00941                 $day = $ndays + ceil(($d+1) / ($_day_power));
00942 
00943                 $d += ($ndays - $day+1)* $_day_power;
00944                 $hour = floor($d/$_hour_power);
00945         
00946         } else {
00947                 for ($a = 1970 ;; $a++) {
00948                         $lastd = $d;
00949                         
00950                         if ($leaf = _adodb_is_leap_year($a)) $d -= $d366;
00951                         else $d -= $d365;
00952                         if ($d < 0) {
00953                                 $year = $a;
00954                                 break;
00955                         }
00956                 }
00957                 $secsInYear = $lastd;
00958                 $d = $lastd;
00959                 $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
00960                 for ($a = 1 ; $a <= 12; $a++) {
00961                         $lastd = $d;
00962                         $d -= $mtab[$a] * $_day_power;
00963                         if ($d < 0) {
00964                                 $month = $a;
00965                                 $ndays = $mtab[$a];
00966                                 break;
00967                         }
00968                 }
00969                 $d = $lastd;
00970                 $day = ceil(($d+1) / $_day_power);
00971                 $d = $d - ($day-1) * $_day_power;
00972                 $hour = floor($d /$_hour_power);
00973         }
00974         
00975         $d -= $hour * $_hour_power;
00976         $min = floor($d/$_min_power);
00977         $secs = $d - $min * $_min_power;
00978         if ($fast) {
00979                 return array(
00980                 'seconds' => $secs,
00981                 'minutes' => $min,
00982                 'hours' => $hour,
00983                 'mday' => $day,
00984                 'mon' => $month,
00985                 'year' => $year,
00986                 'yday' => floor($secsInYear/$_day_power),
00987                 'leap' => $leaf,
00988                 'ndays' => $ndays
00989                 );
00990         }
00991         
00992         
00993         $dow = adodb_dow($year,$month,$day);
00994 
00995         return array(
00996                 'seconds' => $secs,
00997                 'minutes' => $min,
00998                 'hours' => $hour,
00999                 'mday' => $day,
01000                 'wday' => $dow,
01001                 'mon' => $month,
01002                 'year' => $year,
01003                 'yday' => floor($secsInYear/$_day_power),
01004                 'weekday' => gmdate('l',$_day_power*(3+$dow)),
01005                 'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
01006                 0 => $origd
01007         );
01008 }
01009 /*
01010                 if ($isphp5)
01011                                 $dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36); 
01012                         else
01013                                 $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); 
01014                         break;*/
01015 function adodb_tz_offset($gmt,$isphp5)
01016 {
01017         $zhrs = abs($gmt)/3600;
01018         $hrs = floor($zhrs);
01019         if ($isphp5) 
01020                 return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60); 
01021         else
01022                 return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60); 
01023 }
01024 
01025 
01026 function adodb_gmdate($fmt,$d=false)
01027 {
01028         return adodb_date($fmt,$d,true);
01029 }
01030 
01031 // accepts unix timestamp and iso date format in $d
01032 function adodb_date2($fmt, $d=false, $is_gmt=false)
01033 {
01034         if ($d !== false) {
01035                 if (!preg_match( 
01036                         "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 
01037                         ($d), $rr)) return adodb_date($fmt,false,$is_gmt);
01038 
01039                 if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
01040         
01041                 // h-m-s-MM-DD-YY
01042                 if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt);
01043                 else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt);
01044         }
01045         
01046         return adodb_date($fmt,$d,$is_gmt);
01047 }
01048 
01049 
01053 function adodb_date($fmt,$d=false,$is_gmt=false)
01054 {
01055 static $daylight;
01056 global $ADODB_DATETIME_CLASS;
01057 static $jan1_1971;
01058 
01059 
01060         if (!isset($daylight)) {
01061                 $daylight = function_exists('adodb_daylight_sv');
01062                 if (empty($jan1_1971)) $jan1_1971 = mktime(0,0,0,1,1,1971); // we only use date() when > 1970 as adodb_mktime() only uses mktime() when > 1970
01063         }
01064         
01065         if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
01066         if (!defined('ADODB_TEST_DATES')) {
01067                 if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
01068                 
01069                         if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= $jan1_1971) // if windows, must be +ve integer
01070                                 return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
01071 
01072                 }
01073         }
01074         $_day_power = 86400;
01075         
01076         $arr = _adodb_getdate($d,true,$is_gmt);
01077         
01078         if ($daylight) adodb_daylight_sv($arr, $is_gmt);
01079         
01080         $year = $arr['year'];
01081         $month = $arr['mon'];
01082         $day = $arr['mday'];
01083         $hour = $arr['hours'];
01084         $min = $arr['minutes'];
01085         $secs = $arr['seconds'];
01086         
01087         $max = strlen($fmt);
01088         $dates = '';
01089         
01090         $isphp5 = PHP_VERSION >= 5;
01091         
01092         /*
01093                 at this point, we have the following integer vars to manipulate:
01094                 $year, $month, $day, $hour, $min, $secs
01095         */
01096         for ($i=0; $i < $max; $i++) {
01097                 switch($fmt[$i]) {
01098                 case 'e':
01099                         $dates .= date('e');
01100                         break;
01101                 case 'T': 
01102                         if ($ADODB_DATETIME_CLASS) {
01103                                 $dt = new DateTime();
01104                                 $dt->SetDate($year,$month,$day);
01105                                 $dates .= $dt->Format('T');
01106                         } else
01107                                 $dates .= date('T');
01108                         break;
01109                 // YEAR
01110                 case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
01111                 case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
01112                 
01113                         // 4.3.11 uses '04 Jun 2004'
01114                         // 4.3.8 uses  ' 4 Jun 2004'
01115                         $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '         
01116                                 . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
01117                         
01118                         if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; 
01119                         
01120                         if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
01121                         
01122                         if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
01123                         
01124                         $gmt = adodb_get_gmt_diff($year,$month,$day);
01125                         
01126                         $dates .= ' '.adodb_tz_offset($gmt,$isphp5);
01127                         break;
01128                         
01129                 case 'Y': $dates .= $year; break;
01130                 case 'y': $dates .= substr($year,strlen($year)-2,2); break;
01131                 // MONTH
01132                 case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
01133                 case 'Q': $dates .= ($month+3)>>2; break;
01134                 case 'n': $dates .= $month; break;
01135                 case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
01136                 case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
01137                 // DAY
01138                 case 't': $dates .= $arr['ndays']; break;
01139                 case 'z': $dates .= $arr['yday']; break;
01140                 case 'w': $dates .= adodb_dow($year,$month,$day); break;
01141                 case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
01142                 case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
01143                 case 'j': $dates .= $day; break;
01144                 case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
01145                 case 'S': 
01146                         $d10 = $day % 10;
01147                         if ($d10 == 1) $dates .= 'st';
01148                         else if ($d10 == 2 && $day != 12) $dates .= 'nd';
01149                         else if ($d10 == 3) $dates .= 'rd';
01150                         else $dates .= 'th';
01151                         break;
01152                         
01153                 // HOUR
01154                 case 'Z':
01155                         $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff($year,$month,$day); break;
01156                 case 'O': 
01157                         $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day);
01158                         
01159                         $dates .= adodb_tz_offset($gmt,$isphp5);
01160                         break;
01161                         
01162                 case 'H': 
01163                         if ($hour < 10) $dates .= '0'.$hour; 
01164                         else $dates .= $hour; 
01165                         break;
01166                 case 'h': 
01167                         if ($hour > 12) $hh = $hour - 12; 
01168                         else {
01169                                 if ($hour == 0) $hh = '12'; 
01170                                 else $hh = $hour;
01171                         }
01172                         
01173                         if ($hh < 10) $dates .= '0'.$hh;
01174                         else $dates .= $hh;
01175                         break;
01176                         
01177                 case 'G': 
01178                         $dates .= $hour;
01179                         break;
01180                         
01181                 case 'g':
01182                         if ($hour > 12) $hh = $hour - 12; 
01183                         else {
01184                                 if ($hour == 0) $hh = '12'; 
01185                                 else $hh = $hour; 
01186                         }
01187                         $dates .= $hh;
01188                         break;
01189                 // MINUTES
01190                 case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
01191                 // SECONDS
01192                 case 'U': $dates .= $d; break;
01193                 case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
01194                 // AM/PM
01195                 // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
01196                 case 'a':
01197                         if ($hour>=12) $dates .= 'pm';
01198                         else $dates .= 'am';
01199                         break;
01200                 case 'A':
01201                         if ($hour>=12) $dates .= 'PM';
01202                         else $dates .= 'AM';
01203                         break;
01204                 default:
01205                         $dates .= $fmt[$i]; break;
01206                 // ESCAPE
01207                 case "\\": 
01208                         $i++;
01209                         if ($i < $max) $dates .= $fmt[$i];
01210                         break;
01211                 }
01212         }
01213         return $dates;
01214 }
01215 
01220 function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
01221 {
01222         return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
01223 }
01224 
01231 function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false) 
01232 {
01233         if (!defined('ADODB_TEST_DATES')) {
01234 
01235                 if ($mon === false) {
01236                         return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
01237                 }
01238                 
01239                 // for windows, we don't check 1970 because with timezone differences, 
01240                 // 1 Jan 1970 could generate negative timestamp, which is illegal
01241                 $usephpfns = (1970 < $year && $year < 2038
01242                         || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
01243                         ); 
01244                         
01245                 
01246                 if ($usephpfns && ($year + $mon/12+$day/365.25+$hr/(24*365.25) >= 2038)) $usephpfns = false;
01247                         
01248                 if ($usephpfns) {
01249                                 return $is_gmt ?
01250                                         @gmmktime($hr,$min,$sec,$mon,$day,$year):
01251                                         @mktime($hr,$min,$sec,$mon,$day,$year);
01252                 }
01253         }
01254         
01255         $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$mon,$day);
01256 
01257         /*
01258         # disabled because some people place large values in $sec.
01259         # however we need it for $mon because we use an array...
01260         $hr = intval($hr);
01261         $min = intval($min);
01262         $sec = intval($sec);
01263         */
01264         $mon = intval($mon);
01265         $day = intval($day);
01266         $year = intval($year);
01267         
01268         
01269         $year = adodb_year_digit_check($year);
01270 
01271         if ($mon > 12) {
01272                 $y = floor(($mon-1)/ 12);
01273                 $year += $y;
01274                 $mon -= $y*12;
01275         } else if ($mon < 1) {
01276                 $y = ceil((1-$mon) / 12);
01277                 $year -= $y;
01278                 $mon += $y*12;
01279         }
01280         
01281         $_day_power = 86400;
01282         $_hour_power = 3600;
01283         $_min_power = 60;
01284         
01285         $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
01286         $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
01287         
01288         $_total_date = 0;
01289         if ($year >= 1970) {
01290                 for ($a = 1970 ; $a <= $year; $a++) {
01291                         $leaf = _adodb_is_leap_year($a);
01292                         if ($leaf == true) {
01293                                 $loop_table = $_month_table_leaf;
01294                                 $_add_date = 366;
01295                         } else {
01296                                 $loop_table = $_month_table_normal;
01297                                 $_add_date = 365;
01298                         }
01299                         if ($a < $year) { 
01300                                 $_total_date += $_add_date;
01301                         } else {
01302                                 for($b=1;$b<$mon;$b++) {
01303                                         $_total_date += $loop_table[$b];
01304                                 }
01305                         }
01306                 }
01307                 $_total_date +=$day-1;
01308                 $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
01309         
01310         } else {
01311                 for ($a = 1969 ; $a >= $year; $a--) {
01312                         $leaf = _adodb_is_leap_year($a);
01313                         if ($leaf == true) {
01314                                 $loop_table = $_month_table_leaf;
01315                                 $_add_date = 366;
01316                         } else {
01317                                 $loop_table = $_month_table_normal;
01318                                 $_add_date = 365;
01319                         }
01320                         if ($a > $year) { $_total_date += $_add_date;
01321                         } else {
01322                                 for($b=12;$b>$mon;$b--) {
01323                                         $_total_date += $loop_table[$b];
01324                                 }
01325                         }
01326                 }
01327                 $_total_date += $loop_table[$mon] - $day;
01328                 
01329                 $_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
01330                 $_day_time = $_day_power - $_day_time;
01331                 $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
01332                 if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction
01333                 else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.
01334         } 
01335         //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
01336         return $ret;
01337 }
01338 
01339 function adodb_gmstrftime($fmt, $ts=false)
01340 {
01341         return adodb_strftime($fmt,$ts,true);
01342 }
01343 
01344 // hack - convert to adodb_date
01345 function adodb_strftime($fmt, $ts=false,$is_gmt=false)
01346 {
01347 global $ADODB_DATE_LOCALE;
01348 
01349         if (!defined('ADODB_TEST_DATES')) {
01350                 if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
01351                         if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer
01352                                 return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts);
01353 
01354                 }
01355         }
01356         
01357         if (empty($ADODB_DATE_LOCALE)) {
01358         /*
01359                 $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am
01360                 $sep = substr($tstr,2,1);
01361                 $hasAM = strrpos($tstr,'M') !== false;
01362         */
01363                 # see http://phplens.com/lens/lensforum/msgs.php?id=14865 for reasoning, and changelog for version 0.24
01364                 $dstr = gmstrftime('%x',31366800); // 30 Dec 1970, 1 am
01365                 $sep = substr($dstr,2,1);
01366                 $tstr = strtoupper(gmstrftime('%X',31366800)); // 30 Dec 1970, 1 am
01367                 $hasAM = strrpos($tstr,'M') !== false;
01368                 
01369                 $ADODB_DATE_LOCALE = array();
01370                 $ADODB_DATE_LOCALE[] =  strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y';     
01371                 $ADODB_DATE_LOCALE[]  = ($hasAM) ? 'h:i:s a' : 'H:i:s';
01372                         
01373         }
01374         $inpct = false;
01375         $fmtdate = '';
01376         for ($i=0,$max = strlen($fmt); $i < $max; $i++) {
01377                 $ch = $fmt[$i];
01378                 if ($ch == '%') {
01379                         if ($inpct) {
01380                                 $fmtdate .= '%';
01381                                 $inpct = false;
01382                         } else
01383                                 $inpct = true;
01384                 } else if ($inpct) {
01385                 
01386                         $inpct = false;
01387                         switch($ch) {
01388                         case '0':
01389                         case '1':
01390                         case '2':
01391                         case '3':
01392                         case '4':
01393                         case '5':
01394                         case '6':
01395                         case '7':
01396                         case '8':
01397                         case '9':
01398                         case 'E':
01399                         case 'O':
01400                                 /* ignore format modifiers */
01401                                 $inpct = true; 
01402                                 break;
01403                                 
01404                         case 'a': $fmtdate .= 'D'; break;
01405                         case 'A': $fmtdate .= 'l'; break;
01406                         case 'h':
01407                         case 'b': $fmtdate .= 'M'; break;
01408                         case 'B': $fmtdate .= 'F'; break;
01409                         case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break;
01410                         case 'C': $fmtdate .= '\C?'; break; // century
01411                         case 'd': $fmtdate .= 'd'; break;
01412                         case 'D': $fmtdate .= 'm/d/y'; break;
01413                         case 'e': $fmtdate .= 'j'; break;
01414                         case 'g': $fmtdate .= '\g?'; break; //?
01415                         case 'G': $fmtdate .= '\G?'; break; //?
01416                         case 'H': $fmtdate .= 'H'; break;
01417                         case 'I': $fmtdate .= 'h'; break;
01418                         case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd
01419                         case 'm': $fmtdate .= 'm'; break;
01420                         case 'M': $fmtdate .= 'i'; break;
01421                         case 'n': $fmtdate .= "\n"; break;
01422                         case 'p': $fmtdate .= 'a'; break;
01423                         case 'r': $fmtdate .= 'h:i:s a'; break;
01424                         case 'R': $fmtdate .= 'H:i:s'; break;
01425                         case 'S': $fmtdate .= 's'; break;
01426                         case 't': $fmtdate .= "\t"; break;
01427                         case 'T': $fmtdate .= 'H:i:s'; break;
01428                         case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based
01429                         case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based
01430                         case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break;
01431                         case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break;
01432                         case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based
01433                         case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based
01434                         case 'y': $fmtdate .= 'y'; break;
01435                         case 'Y': $fmtdate .= 'Y'; break;
01436                         case 'Z': $fmtdate .= 'T'; break;
01437                         }
01438                 } else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' ))
01439                         $fmtdate .= "\\".$ch;
01440                 else
01441                         $fmtdate .= $ch;
01442         }
01443         //echo "fmt=",$fmtdate,"<br>";
01444         if ($ts === false) $ts = time();
01445         $ret = adodb_date($fmtdate, $ts, $is_gmt);
01446         return $ret;
01447 }
01448 
01449 
01450 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations