source: companies/celepar/phpgwapi/inc/adodb/adodb-time.inc.php @ 763

Revision 763, 38.9 KB checked in by niltonneto, 15 years ago (diff)

Importação inicial do Expresso da Celepar

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