Updated ADOdb Date Time Library to v0.32

Includes important fixes for PHP 5
This commit is contained in:
Raphaël Doursenaud 2014-05-03 19:48:30 +02:00
parent e1d30837e9
commit 6cd5d2724a
2 changed files with 673 additions and 248 deletions

View File

@ -12,7 +12,7 @@ Dolibarr uses some external libraries released under different licences. This is
Composant Version License Compatible GPL Usage Composant Version License Compatible GPL Usage
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
PHP libraries: PHP libraries:
AdoDb-Date 0.21 Modified BSD License Yes Date convertion (not into rpm package) AdoDb-Date 0.32 Modified BSD License Yes Date convertion (not into rpm package)
CKEditor 3.6.4 LGPL-2.1+ Yes Editor WYSIWYG CKEditor 3.6.4 LGPL-2.1+ Yes Editor WYSIWYG
FPDI 1.4.2 Apache Software License 2.0 Yes PDF templates management (with FPDF_TPL 1.2) FPDI 1.4.2 Apache Software License 2.0 Yes PDF templates management (with FPDF_TPL 1.2)
GeoIP 2004 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package) GeoIP 2004 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package)

View File

@ -1,12 +1,8 @@
<?php <?php
/** /**
* Copyright (C) 2003-2005 John Lim ADOdb Date Library, part of the ADOdb abstraction library
* Copyright (C) Jackbbs Download: http://phplens.com/phpeverywhere/
*
* This file is released under BSD-style license
*/
/* =============================================================================
PHP native date functions use integer timestamps for computations. PHP native date functions use integer timestamps for computations.
Because of this, dates are restricted to the years 1901-2038 on Unix Because of this, dates are restricted to the years 1901-2038 on Unix
and 1970-2038 on Windows due to integer overflow for dates beyond and 1970-2038 on Windows due to integer overflow for dates beyond
@ -59,6 +55,14 @@ adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
============================================================================= =============================================================================
COPYRIGHT
(c) 2003-2005 John Lim and released under BSD-style license except for code by
jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
and originally found at http://www.php.net/manual/en/function.mktime.php
=============================================================================
BUG REPORTS BUG REPORTS
These should be posted to the ADOdb forums at These should be posted to the ADOdb forums at
@ -104,7 +108,7 @@ The format fields that adodb_date supports:
n - month without leading zeros; i.e. "1" to "12" n - month without leading zeros; i.e. "1" to "12"
O - Difference to Greenwich time in hours; e.g. "+0200" O - Difference to Greenwich time in hours; e.g. "+0200"
Q - Quarter, as in 1, 2, 3, 4 Q - Quarter, as in 1, 2, 3, 4
r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" r - RFC 2822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200"
s - seconds; i.e. "00" to "59" s - seconds; i.e. "00" to "59"
S - English ordinal suffix for the day of the month, 2 characters; S - English ordinal suffix for the day of the month, 2 characters;
i.e. "st", "nd", "rd" or "th" i.e. "st", "nd", "rd" or "th"
@ -129,12 +133,34 @@ Unsupported:
</pre> </pre>
** FUNCTION adodb_date2($fmt, $isoDateString = false)
Same as adodb_date, but 2nd parameter accepts iso date, eg.
adodb_date2('d-M-Y H:i','2003-12-25 13:01:34');
** FUNCTION adodb_gmdate($fmt, $timestamp = false)
Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the
current timestamp is used. Unlike the function date(), it supports dates
outside the 1901 to 2038 range.
** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year]) ** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year])
Converts a local date to a unix timestamp. Unlike the function mktime(), it supports Converts a local date to a unix timestamp. Unlike the function mktime(), it supports
dates outside the 1901 to 2038 range. All parameters are optional. dates outside the 1901 to 2038 range. All parameters are optional.
** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year])
Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports
dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters
are currently compulsory.
** FUNCTION adodb_gmstrftime($fmt, $timestamp = false)
Convert a timestamp to a formatted GMT date.
** FUNCTION adodb_strftime($fmt, $timestamp = false) ** FUNCTION adodb_strftime($fmt, $timestamp = false)
Convert a timestamp to a formatted local date. Internally converts $fmt into Convert a timestamp to a formatted local date. Internally converts $fmt into
@ -216,9 +242,36 @@ b. Implement daylight savings, which looks awfully complicated, see
CHANGELOG CHANGELOG
- 18 July 2005 0.21 - 11 Feb 2008 0.33
- In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat. * Bug in 0.32 fix for hour handling. Fixed.
- Added support for negative months in adodb_mktime().
- 1 Feb 2008 0.32
* Now adodb_mktime(0,0,0,12+$m,20,2040) works properly.
- 10 Jan 2008 0.31
* Now adodb_mktime(0,0,0,24,1,2037) works correctly.
- 15 July 2007 0.30
Added PHP 5.2.0 compatability fixes.
* gmtime behaviour for 1970 has changed. We use the actual date if it is between 1970 to 2038 to get the
* timezone, otherwise we use the current year as the baseline to retrieve the timezone.
* Also the timezone's in php 5.2.* support historical data better, eg. if timezone today was +8, but
in 1970 it was +7:30, then php 5.2 return +7:30, while this library will use +8.
*
- 19 March 2006 0.24
Changed strftime() locale detection, because some locales prepend the day of week to the date when %c is used.
- 10 Feb 2006 0.23
PHP5 compat: when we detect PHP5, the RFC2822 format for gmt 0000hrs is changed from -0000 to +0000.
In PHP4, we will still use -0000 for 100% compat with PHP4.
- 08 Sept 2005 0.22
In adodb_date2(), $is_gmt not supported properly. Fixed.
- 18 July 2005 0.21
In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat.
Added support for negative months in adodb_mktime().
- 24 Feb 2005 0.20 - 24 Feb 2005 0.20
Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date(). Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date().
@ -333,7 +386,9 @@ First implementation.
/* /*
Version Number Version Number
*/ */
define('ADODB_DATE_VERSION',0.21); define('ADODB_DATE_VERSION',0.33);
$ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
/* /*
This code was originally for windows. But apparently this problem happens This code was originally for windows. But apparently this problem happens
@ -350,12 +405,207 @@ define('ADODB_DATE_VERSION',0.21);
if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1); if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
function adodb_date_test_date($y1,$m,$d=13)
{
$h = round(rand()% 24);
$t = adodb_mktime($h,0,0,$m,$d,$y1);
$rez = adodb_date('Y-n-j H:i:s',$t);
if ($h == 0) $h = '00';
else if ($h < 10) $h = '0'.$h;
if ("$y1-$m-$d $h:00:00" != $rez) {
print "<b>$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez</b><br>";
return false;
}
return true;
}
function adodb_date_test_strftime($fmt)
{
$s1 = strftime($fmt);
$s2 = adodb_strftime($fmt);
if ($s1 == $s2) return true;
echo "error for $fmt, strftime=$s1, adodb=$s2<br>";
return false;
}
/**
Test Suite
*/
function adodb_date_test()
{
for ($m=-24; $m<=24; $m++)
echo "$m :",adodb_date('d-m-Y',adodb_mktime(0,0,0,1+$m,20,2040)),"<br>";
error_reporting(E_ALL);
print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>";
@set_time_limit(0);
$fail = false;
// This flag disables calling of PHP native functions, so we can properly test the code
if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
$t = time();
$fmt = 'Y-m-d H:i:s';
echo '<pre>';
echo 'adodb: ',adodb_date($fmt,$t),'<br>';
echo 'php : ',date($fmt,$t),'<br>';
echo '</pre>';
adodb_date_test_strftime('%Y %m %x %X');
adodb_date_test_strftime("%A %d %B %Y");
adodb_date_test_strftime("%H %M S");
$t = adodb_mktime(0,0,0);
if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
$t = adodb_mktime(0,0,0,6,1,2102);
if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
$t = adodb_mktime(0,0,0,2,1,2102);
if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
print "<p>Testing gregorian <=> julian conversion<p>";
$t = adodb_mktime(0,0,0,10,11,1492);
//http://www.holidayorigins.com/html/columbus_day.html - Friday check
if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>';
$t = adodb_mktime(0,0,0,2,29,1500);
if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>';
$t = adodb_mktime(0,0,0,2,29,1700);
if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>';
print adodb_mktime(0,0,0,10,4,1582).' ';
print adodb_mktime(0,0,0,10,15,1582);
$diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582));
if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>";
print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>";
print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>";
print "<p>Testing overflow<p>";
$t = adodb_mktime(0,0,0,3,33,1965);
if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>';
$t = adodb_mktime(0,0,0,4,33,1971);
if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>';
$t = adodb_mktime(0,0,0,1,60,1965);
if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>';
$t = adodb_mktime(0,0,0,12,32,1965);
if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>';
$t = adodb_mktime(0,0,0,12,63,1965);
if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>';
$t = adodb_mktime(0,0,0,13,3,1965);
if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>';
print "Testing 2-digit => 4-digit year conversion<p>";
if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>";
if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>";
if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>";
if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>";
if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>";
if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
// Test string formating
print "<p>Testing date formating</p>";
$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';
$s1 = date($fmt,0);
$s2 = adodb_date($fmt,0);
if ($s1 != $s2) {
print " date() 0 failed<br>$s1<br>$s2<br>";
}
flush();
for ($i=100; --$i > 0; ) {
$ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000);
$s1 = date($fmt,$ts);
$s2 = adodb_date($fmt,$ts);
//print "$s1 <br>$s2 <p>";
$pos = strcmp($s1,$s2);
if (($s1) != ($s2)) {
for ($j=0,$k=strlen($s1); $j < $k; $j++) {
if ($s1[$j] != $s2[$j]) {
print substr($s1,$j).' ';
break;
}
}
print "<b>Error date(): $ts<br><pre>
&nbsp; \"$s1\" (date len=".strlen($s1).")
&nbsp; \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>";
$fail = true;
}
$a1 = getdate($ts);
$a2 = adodb_getdate($ts);
$rez = array_diff($a1,$a2);
if (sizeof($rez)>0) {
print "<b>Error getdate() $ts</b><br>";
print_r($a1);
print "<br>";
print_r($a2);
print "<p>";
$fail = true;
}
}
// Test generation of dates outside 1901-2038
print "<p>Testing random dates between 100 and 4000</p>";
adodb_date_test_date(100,1);
for ($i=100; --$i >= 0;) {
$y1 = 100+rand(0,1970-100);
$m = rand(1,12);
adodb_date_test_date($y1,$m);
$y1 = 3000-rand(0,3000-1970);
adodb_date_test_date($y1,$m);
}
print '<p>';
$start = 1960+rand(0,10);
$yrs = 12;
$i = 365.25*86400*($start-1970);
$offset = 36000+rand(10000,60000);
$max = 365*$yrs*86400;
$lastyear = 0;
// we generate a timestamp, convert it to a date, and convert it back to a timestamp
// and check if the roundtrip broke the original timestamp value.
print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
$cnt = 0;
for ($max += $i; $i < $max; $i += $offset) {
$ret = adodb_date('m,d,Y,H,i,s',$i);
$arr = explode(',',$ret);
if ($lastyear != $arr[2]) {
$lastyear = $arr[2];
print " $lastyear ";
flush();
}
$newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]);
if ($i != $newi) {
print "Error at $i, adodb_mktime returned $newi ($ret)";
$fail = true;
break;
}
$cnt += 1;
}
echo "Tested $cnt dates<br>";
if (!$fail) print "<p>Passed !</p>";
else print "<p><b>Failed</b> :-(</p>";
}
/** /**
Returns day of week, 0 = Sunday,... 6=Saturday. Returns day of week, 0 = Sunday,... 6=Saturday.
Algorithm from PEAR::Date_Calc Algorithm from PEAR::Date_Calc
*/ */
function _adodb_dow($year, $month, $day) function adodb_dow($year, $month, $day)
{ {
/* /*
Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
@ -408,6 +658,14 @@ function _adodb_is_leap_year($year)
} }
/**
checks for leap year, returns true if it is. Has 2-digit year check
*/
function adodb_is_leap_year($year)
{
return _adodb_is_leap_year(adodb_year_digit_check($year));
}
/** /**
Fix 2-digit years. Works for any century. Fix 2-digit years. Works for any century.
Assumes that if 2-digit is more than 30 years in future, then previous century. Assumes that if 2-digit is more than 30 years in future, then previous century.
@ -435,17 +693,45 @@ function adodb_year_digit_check($y)
return $y; return $y;
} }
/** function adodb_get_gmt_diff_ts($ts)
get local time zone offset from GMT
*/
function adodb_get_gmt_diff()
{ {
static $TZ; if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) {
if (isset($TZ)) return $TZ; $arr = getdate($ts);
$y = $arr['year'];
$m = $arr['mon'];
$d = $arr['mday'];
return adodb_get_gmt_diff($y,$m,$d);
} else {
return adodb_get_gmt_diff(false,false,false);
}
}
/**
get local time zone offset from GMT. Does not handle historical timezones before 1970.
*/
function adodb_get_gmt_diff($y,$m,$d)
{
static $TZ,$tzo;
global $ADODB_DATETIME_CLASS;
if (!defined('ADODB_TEST_DATES')) $y = false;
else if ($y < 1970 || $y >= 2038) $y = false;
if ($ADODB_DATETIME_CLASS && $y !== false) {
$dt = new DateTime();
$dt->setISODate($y,$m,$d);
if (empty($tzo)) {
$tzo = new DateTimeZone(date_default_timezone_get());
# $tzt = timezone_transitions_get( $tzo );
}
return -$tzo->getOffset($dt);
} else {
if (isset($TZ)) return $TZ;
$y = date('Y');
$TZ = mktime(0,0,0,12,2,$y,0) - gmmktime(0,0,0,12,2,$y,0);
}
// $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0);
// LDR Fix To avoid warning on PHP 5.1
$TZ = mktime(0,0,0,1,2,1970) - gmmktime(0,0,0,1,2,1970);
return $TZ; return $TZ;
} }
@ -464,6 +750,47 @@ function adodb_getdate($d=false,$fast=false)
return _adodb_getdate($d); return _adodb_getdate($d);
} }
/*
// generate $YRS table for _adodb_getdate()
function adodb_date_gentable($out=true)
{
for ($i=1970; $i >= 1600; $i-=10) {
$s = adodb_gmmktime(0,0,0,1,1,$i);
echo "$i => $s,<br>";
}
}
adodb_date_gentable();
for ($i=1970; $i > 1500; $i--) {
echo "<hr />$i ";
adodb_date_test_date($i,1,1);
}
*/
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
function adodb_validdate($y,$m,$d)
{
global $_month_table_normal,$_month_table_leaf;
if (_adodb_is_leap_year($y)) $marr = $_month_table_leaf;
else $marr = $_month_table_normal;
if ($m > 12 || $m < 1) return false;
if ($d > 31 || $d < 1) return false;
if ($marr[$m] < $d) return false;
if ($y < 1000 && $y > 3000) return false;
return true;
}
/** /**
Low-level function that returns the getdate() array. We have a special Low-level function that returns the getdate() array. We have a special
@ -472,10 +799,10 @@ function adodb_getdate($d=false,$fast=false)
*/ */
function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
{ {
static $YRS; static $YRS;
global $_month_table_normal,$_month_table_leaf;
$d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff());
$d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff_ts($origd));
$_day_power = 86400; $_day_power = 86400;
$_hour_power = 3600; $_hour_power = 3600;
$_min_power = 60; $_min_power = 60;
@ -535,6 +862,24 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
// Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
// //
# old algorithm iterates through all years. new algorithm does it in
# 10 year blocks
/*
# old algo
for ($a = 1970 ; --$a >= 0;) {
$lastd = $d;
if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
else $d += $d365;
if ($d >= 0) {
$year = $a;
break;
}
}
*/
$lastsecs = 0; $lastsecs = 0;
$lastyear = 1970; $lastyear = 1970;
foreach($YRS as $year => $secs) { foreach($YRS as $year => $secs) {
@ -631,7 +976,7 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
} }
$dow = _adodb_dow($year,$month,$day); $dow = adodb_dow($year,$month,$day);
return array( return array(
'seconds' => $secs, 'seconds' => $secs,
@ -647,6 +992,47 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
0 => $origd 0 => $origd
); );
} }
/*
if ($isphp5)
$dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36);
else
$dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36);
break;*/
function adodb_tz_offset($gmt,$isphp5)
{
$zhrs = abs($gmt)/3600;
$hrs = floor($zhrs);
if ($isphp5)
return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
else
return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
break;
}
function adodb_gmdate($fmt,$d=false)
{
return adodb_date($fmt,$d,true);
}
// accepts unix timestamp and iso date format in $d
function adodb_date2($fmt, $d=false, $is_gmt=false)
{
if ($d !== false) {
if (!preg_match(
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
($d), $rr)) return adodb_date($fmt,false,$is_gmt);
if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
// h-m-s-MM-DD-YY
if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt);
else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt);
}
return adodb_date($fmt,$d,$is_gmt);
}
/** /**
Return formatted date based on timestamp $d Return formatted date based on timestamp $d
@ -654,6 +1040,7 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
function adodb_date($fmt,$d=false,$is_gmt=false) function adodb_date($fmt,$d=false,$is_gmt=false)
{ {
static $daylight; static $daylight;
global $ADODB_DATETIME_CLASS;
if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt); if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
if (!defined('ADODB_TEST_DATES')) { if (!defined('ADODB_TEST_DATES')) {
@ -680,20 +1067,29 @@ static $daylight;
$max = strlen($fmt); $max = strlen($fmt);
$dates = ''; $dates = '';
$isphp5 = PHP_VERSION >= 5;
/* /*
at this point, we have the following integer vars to manipulate: at this point, we have the following integer vars to manipulate:
$year, $month, $day, $hour, $min, $secs $year, $month, $day, $hour, $min, $secs
*/ */
for ($i=0; $i < $max; $i++) { for ($i=0; $i < $max; $i++) {
switch($fmt[$i]) { switch($fmt[$i]) {
case 'T': $dates .= date('T');break; case 'T':
if ($ADODB_DATETIME_CLASS) {
$dt = new DateTime();
$dt->SetDate($year,$month,$day);
$dates .= $dt->Format('T');
} else
$dates .= date('T');
break;
// YEAR // YEAR
case 'L': $dates .= $arr['leap'] ? '1' : '0'; break; case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
case 'r': // Thu, 21 Dec 2000 16:01:07 +0200 case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
// 4.3.11 uses '04 Jun 2004' // 4.3.11 uses '04 Jun 2004'
// 4.3.8 uses ' 4 Jun 2004' // 4.3.8 uses ' 4 Jun 2004'
$dates .= gmdate('D',$_day_power*(3+_adodb_dow($year,$month,$day))).', ' $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '
. ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' '; . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour;
@ -702,8 +1098,10 @@ static $daylight;
if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs; if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
$gmt = adodb_get_gmt_diff(); $gmt = adodb_get_gmt_diff($year,$month,$day);
$dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
$dates .= ' '.adodb_tz_offset($gmt,$isphp5);
break;
case 'Y': $dates .= $year; break; case 'Y': $dates .= $year; break;
case 'y': $dates .= substr($year,strlen($year)-2,2); break; case 'y': $dates .= substr($year,strlen($year)-2,2); break;
@ -716,9 +1114,9 @@ static $daylight;
// DAY // DAY
case 't': $dates .= $arr['ndays']; break; case 't': $dates .= $arr['ndays']; break;
case 'z': $dates .= $arr['yday']; break; case 'z': $dates .= $arr['yday']; break;
case 'w': $dates .= _adodb_dow($year,$month,$day); break; case 'w': $dates .= adodb_dow($year,$month,$day); break;
case 'l': $dates .= gmdate('l',$_day_power*(3+_adodb_dow($year,$month,$day))); break; case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
case 'D': $dates .= gmdate('D',$_day_power*(3+_adodb_dow($year,$month,$day))); break; case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
case 'j': $dates .= $day; break; case 'j': $dates .= $day; break;
case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break; case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
case 'S': case 'S':
@ -731,10 +1129,12 @@ static $daylight;
// HOUR // HOUR
case 'Z': case 'Z':
$dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break; $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff($year,$month,$day); break;
case 'O': case 'O':
$gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff(); $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day);
$dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
$dates .= adodb_tz_offset($gmt,$isphp5);
break;
case 'H': case 'H':
if ($hour < 10) $dates .= '0'.$hour; if ($hour < 10) $dates .= '0'.$hour;
@ -790,6 +1190,15 @@ static $daylight;
return $dates; return $dates;
} }
/**
Returns a timestamp given a GMT/UTC time.
Note that $is_dst is not implemented and is ignored.
*/
function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
{
return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
}
/** /**
Return a timestamp given a local time. Originally by jackbbs. Return a timestamp given a local time. Originally by jackbbs.
Note that $is_dst is not implemented and is ignored. Note that $is_dst is not implemented and is ignored.
@ -806,16 +1215,21 @@ function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=fa
// for windows, we don't check 1970 because with timezone differences, // for windows, we don't check 1970 because with timezone differences,
// 1 Jan 1970 could generate negative timestamp, which is illegal // 1 Jan 1970 could generate negative timestamp, which is illegal
if (1971 < $year && $year < 2038 $usephpfns = (1971 < $year && $year < 2038
|| !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038) || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
) { );
if ($usephpfns && ($year + $mon/12+$day/365.25+$hr/(24*365.25) >= 2038)) $usephpfns = false;
if ($usephpfns) {
return $is_gmt ? return $is_gmt ?
@gmmktime($hr,$min,$sec,$mon,$day,$year): @gmmktime($hr,$min,$sec,$mon,$day,$year):
@mktime($hr,$min,$sec,$mon,$day,$year); @mktime($hr,$min,$sec,$mon,$day,$year);
} }
} }
$gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff(); $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$mon,$day);
/* /*
# disabled because some people place large values in $sec. # disabled because some people place large values in $sec.
@ -832,7 +1246,7 @@ function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=fa
$year = adodb_year_digit_check($year); $year = adodb_year_digit_check($year);
if ($mon > 12) { if ($mon > 12) {
$y = floor($mon / 12); $y = floor(($mon-1)/ 12);
$year += $y; $year += $y;
$mon -= $y*12; $mon -= $y*12;
} else if ($mon < 1) { } else if ($mon < 1) {
@ -899,6 +1313,11 @@ function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=fa
return $ret; return $ret;
} }
function adodb_gmstrftime($fmt, $ts=false)
{
return adodb_strftime($fmt,$ts,true);
}
// hack - convert to adodb_date // hack - convert to adodb_date
function adodb_strftime($fmt, $ts=false,$is_gmt=false) function adodb_strftime($fmt, $ts=false,$is_gmt=false)
{ {
@ -913,9 +1332,16 @@ global $ADODB_DATE_LOCALE;
} }
if (empty($ADODB_DATE_LOCALE)) { if (empty($ADODB_DATE_LOCALE)) {
/*
$tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am
$sep = substr($tstr,2,1); $sep = substr($tstr,2,1);
$hasAM = strrpos($tstr,'M') !== false; $hasAM = strrpos($tstr,'M') !== false;
*/
# see http://phplens.com/lens/lensforum/msgs.php?id=14865 for reasoning, and changelog for version 0.24
$dstr = gmstrftime('%x',31366800); // 30 Dec 1970, 1 am
$sep = substr($dstr,2,1);
$tstr = strtoupper(gmstrftime('%X',31366800)); // 30 Dec 1970, 1 am
$hasAM = strrpos($tstr,'M') !== false;
$ADODB_DATE_LOCALE = array(); $ADODB_DATE_LOCALE = array();
$ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y'; $ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y';
@ -976,11 +1402,11 @@ global $ADODB_DATE_LOCALE;
case 'S': $fmtdate .= 's'; break; case 'S': $fmtdate .= 's'; break;
case 't': $fmtdate .= "\t"; break; case 't': $fmtdate .= "\t"; break;
case 'T': $fmtdate .= 'H:i:s'; break; case 'T': $fmtdate .= 'H:i:s'; break;
case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-basde case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based
case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based
case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break; case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break;
case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break; case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break;
case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-basde case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based
case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based
case 'y': $fmtdate .= 'y'; break; case 'y': $fmtdate .= 'y'; break;
case 'Y': $fmtdate .= 'Y'; break; case 'Y': $fmtdate .= 'Y'; break;
@ -997,5 +1423,4 @@ global $ADODB_DATE_LOCALE;
return $ret; return $ret;
} }
?> ?>