| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: date_php4_lib.inc,v 1.4.4.7 2009/02/24 17:14:06 karens Exp $ 3 4 /** 5 * Date Library, extended date functions. 6 * File is included only when needed. 7 */ 8 9 /** 10 * @ingroup adodb 11 * @{ 12 */ 13 /** 14 * The following functions are low level functions that implements pre 1970 15 * to post 2038 versions of native php date functions. Will handle dates from 16 * the year 100 to the year 3000. Uses native php date functions when possible, 17 * alterate methods when native functions won't work. 18 * 19 * Altered the original ADODB code to split it between the high level 20 * functions which are used when pre-1970 and post-2038 dates are not needed 21 * and this large file which is only parsed for dates that are out of range 22 * for native php date handling. 23 * 24 * Replace native php functions: 25 * getdate() with date_getdate() 26 * date() with date_date() 27 * gmdate() with date_gmdate() 28 * mktime() with date_mktime() 29 * gmmktime() with gmdate_mktime() 30 * 31 * The following functions were derived from code obtained from 32 * http://phplens.com/phpeverywhere/adodb_date_library, licensed as follows: 33 * 34 * COPYRIGHT(c) 2003-2005 John Lim 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted under the terms of the BSD License. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 43 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 44 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 45 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 46 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 48 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 50 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51 * POSSIBILITY OF SUCH DAMAGE. 52 */ 53 54 /** 55 * Low-level function that returns the getdate() array for pre-1970 56 * and post-2038 dates. 57 * 58 * We have a special$fast flag, which if set to true, will return fewer 59 * array values, and is much faster as it does not calculate dow, etc. 60 * 61 * @param $timestamp a unix timestamp 62 * @param $timezone name 63 * Use 'UTC' to avoid timezone conversion. 64 */ 65 function _date_getdate($timestamp = false, $timezone = false) { 66 static $YRS; 67 if ($timezone === FALSE) { 68 $timezone = date_default_timezone_name(); 69 } 70 71 $timestamp_in = $timestamp; 72 73 $_day_power = 86400; 74 $_hour_power = 3600; 75 $_min_power = 60; 76 if ($timestamp < -12219321600) $timestamp -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction 77 $_month_table_normal = array("", 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 78 $_month_table_leap = array("", 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 79 $d366 = $_day_power * 366; 80 $d365 = $_day_power * 365; 81 if ($timestamp < 0) { 82 if (empty($YRS)) $YRS = array( 83 1970 => 0, 84 1960 => -315619200, 85 1950 => -631152000, 86 1940 => -946771200, 87 1930 => -1262304000, 88 1920 => -1577923200, 89 1910 => -1893456000, 90 1900 => -2208988800, 91 1890 => -2524521600, 92 1880 => -2840140800, 93 1870 => -3155673600, 94 1860 => -3471292800, 95 1850 => -3786825600, 96 1840 => -4102444800, 97 1830 => -4417977600, 98 1820 => -4733596800, 99 1810 => -5049129600, 100 1800 => -5364662400, 101 1790 => -5680195200, 102 1780 => -5995814400, 103 1770 => -6311347200, 104 1760 => -6626966400, 105 1750 => -6942499200, 106 1740 => -7258118400, 107 1730 => -7573651200, 108 1720 => -7889270400, 109 1710 => -8204803200, 110 1700 => -8520336000, 111 1690 => -8835868800, 112 1680 => -9151488000, 113 1670 => -9467020800, 114 1660 => -9782640000, 115 1650 => -10098172800, 116 1640 => -10413792000, 117 1630 => -10729324800, 118 1620 => -11044944000, 119 1610 => -11360476800, 120 1600 => -11676096000); 121 122 // The valid range of a 32bit signed timestamp is typically from 123 // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT 124 // 125 $lastsecs = 0; 126 $lastyear = 1970; 127 foreach ($YRS as $year => $secs) { 128 if ($timestamp >= $secs) { 129 $a = $lastyear; 130 break; 131 } 132 $lastsecs = $secs; 133 $lastyear = $year; 134 } 135 $timestamp -= $lastsecs; 136 if (!isset($a)) $a = $lastyear; 137 for (; --$a >= 0;) { 138 $lastd = $timestamp; 139 if ($leap = date_is_leap_year($a)) $timestamp += $d366; 140 else $timestamp += $d365; 141 142 if ($timestamp >= 0) { 143 $year = $a; 144 break; 145 } 146 } 147 $secs_in_year = 86400 * ($leap ? 366 : 365) + $lastd; 148 $timestamp = $lastd; 149 $mtab = ($leap) ? $_month_table_leap : $_month_table_normal; 150 for ($a = 13 ; --$a > 0;) { 151 $lastd = $timestamp; 152 $timestamp += $mtab[$a] * $_day_power; 153 if ($timestamp >= 0) { 154 $month = $a; 155 $ndays = $mtab[$a]; 156 break; 157 } 158 } 159 $timestamp = $lastd; 160 $day = $ndays + ceil(($timestamp+1) / ($_day_power)); 161 $timestamp += ($ndays - $day+1)* $_day_power; 162 $hour = floor($timestamp/$_hour_power); 163 } 164 else { 165 166 if ($timezone != 'UTC') { 167 $timestamp += date_get_gmt_diff_ts($timestamp, $timezone); 168 } 169 170 for ($a = 1970 ;; $a++) { 171 $lastd = $timestamp; 172 if ($leap = date_is_leap_year($a)) $timestamp -= $d366; 173 else $timestamp -= $d365; 174 if ($timestamp < 0) { 175 $year = $a; 176 break; 177 } 178 } 179 $secs_in_year = $lastd; 180 $timestamp = $lastd; 181 $mtab = ($leap) ? $_month_table_leap : $_month_table_normal; 182 for ($a = 1 ; $a <= 12; $a++) { 183 $lastd = $timestamp; 184 $timestamp -= $mtab[$a] * $_day_power; 185 if ($timestamp < 0) { 186 $month = $a; 187 $ndays = $mtab[$a]; 188 break; 189 } 190 } 191 $timestamp = $lastd; 192 $day = ceil(($timestamp + 1) / $_day_power); 193 $timestamp = $timestamp - ($day - 1) * $_day_power; 194 $hour = floor($timestamp / $_hour_power); 195 } 196 $timestamp -= $hour * $_hour_power; 197 $min = floor($timestamp / $_min_power); 198 $secs = $timestamp - $min * $_min_power; 199 $dow = date_dow($day, $month, $year); 200 return array( 201 'second' => $secs, 202 'minute' => $min, 203 'hour' => $hour, 204 'day' => $day, 205 'wday' => $dow, 206 'month' => $month, 207 'year' => $year, 208 'yday' => floor($secs_in_year / $_day_power), 209 'weekday' => gmdate('l', ($_day_power * (3 + $dow))), 210 'leap' => $leap, 211 'ndays' => $ndays, 212 'month_name' => gmdate('F', mktime(0, 0, 0, $month, 2, 1971)), 213 0 => $timestamp_in 214 ); 215 } 216 217 /** 218 * Low level function to create date() for pre-1970 and post-2038 dates. 219 * 220 * @param $format a format string for the result 221 * @param $timestamp a unix timestamp 222 * @param $timezone name 223 * Use 'UTC' to avoid timezone conversion. 224 */ 225 function _date_date($format, $timestamp = false, $timezone = false) { 226 if ($timezone === FALSE) { 227 $timezone = date_default_timezone_name(); 228 } 229 230 $_day_power = 86400; 231 $arr = _date_getdate($timestamp, $timezone); 232 $year = $arr['year']; 233 $month = $arr['month']; 234 $day = $arr['day']; 235 $hour = $arr['hour']; 236 $min = $arr['minute']; 237 $secs = $arr['second']; 238 $max = strlen($format); 239 $dates = ''; 240 241 /* 242 at this point, we have the following integer vars to manipulate: 243 $year, $month, $day, $hour, $min, $secs 244 */ 245 for ($i = 0; $i < $max; $i++) { 246 switch ($format[$i]) { 247 case 'T': $dates .= date('T');break; 248 // YEAR 249 case 'L': $dates .= $arr['leap'] ? '1' : '0'; break; 250 case 'r': // Thu, 21 Dec 2000 16:01:07 +0200 251 // 4.3.11 uses '04 Jun 2004' 252 // 4.3.8 uses ' 4 Jun 2004' 253 $dates .= gmdate('D', $_day_power*(3 + date_dow($day, $month, $year))) .', '. 254 ($day < 10 ? '0'. $day : $day) .' '. date('M', mktime(0, 0, 0, $month, 2, 1971)) .' '. $year .' '; 255 if ($hour < 10) $dates .= '0'. $hour; else $dates .= $hour; 256 if ($min < 10) $dates .= ':0'. $min; else $dates .= ':'. $min; 257 if ($secs < 10) $dates .= ':0'. $secs; else $dates .= ':'. $secs; 258 $gmt = date_get_gmt_diff_ts($timestamp, $timezone); 259 $dates .= sprintf(' %s%04d', ($gmt >= 0) ? '+' : '-', abs($gmt) / 36); break; 260 case 'Y': $dates .= date_pad($year, 4); break; 261 case 'y': $dates .= substr($year, strlen($year)-2, 2); break; 262 // MONTH 263 case 'm': if ($month<10) $dates .= '0'. $month; else $dates .= $month; break; 264 case 'Q': $dates .= ($month + 3)>>2; break; 265 case 'n': $dates .= $month; break; 266 case 'M': $dates .= date('M', mktime(0, 0, 0, $month, 2, 1971)); break; 267 case 'F': $dates .= date('F', mktime(0, 0, 0, $month, 2, 1971)); break; 268 // DAY 269 case 't': $dates .= $arr['ndays']; break; 270 case 'z': $dates .= $arr['yday']; break; 271 case 'w': $dates .= date_dow($day, $month, $year); break; 272 case 'l': $dates .= gmdate('l', $_day_power*(3 + date_dow($day, $month, $year))); break; 273 case 'D': $dates .= gmdate('D', $_day_power*(3 + date_dow($day, $month, $year))); break; 274 case 'j': $dates .= $day; break; 275 case 'd': if ($day<10) $dates .= '0'. $day; else $dates .= $day; break; 276 case 'S': 277 $d10 = $day % 10; 278 if ($d10 == 1) $dates .= 'st'; 279 else if ($d10 == 2 && $day != 12) $dates .= 'nd'; 280 else if ($d10 == 3) $dates .= 'rd'; 281 else $dates .= 'th'; 282 break; 283 // HOUR 284 case 'Z': 285 $dates .= -date_get_gmt_diff_ts($timestamp, $timezone); 286 break; 287 case 'O': 288 $gmt = date_get_gmt_diff_ts($timestamp, $timezone); 289 $dates .= sprintf('%s%04d', ($gmt<0)?'+':'-', abs($gmt)/36); 290 break; 291 case 'H': 292 if ($hour < 10) $dates .= '0'. $hour; 293 else $dates .= $hour; 294 break; 295 case 'h': 296 if ($hour > 12) $hh = $hour - 12; 297 else { 298 if ($hour == 0) $hh = '12'; 299 else $hh = $hour; 300 } 301 if ($hh < 10) $dates .= '0'. $hh; 302 else $dates .= $hh; 303 break; 304 case 'G': 305 $dates .= $hour; 306 break; 307 case 'g': 308 if ($hour > 12) $hh = $hour - 12; 309 else { 310 if ($hour == 0) $hh = '12'; 311 else $hh = $hour; 312 } 313 $dates .= $hh; 314 break; 315 // MINUTES 316 case 'i': if ($min < 10) $dates .= '0'. $min; else $dates .= $min; break; 317 // SECONDS 318 case 'U': $dates .= $timestamp; break; 319 case 's': if ($secs < 10) $dates .= '0'. $secs; else $dates .= $secs; break; 320 // AM/PM 321 // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM 322 case 'a': 323 if ($hour>=12) $dates .= 'pm'; 324 else $dates .= 'am'; 325 break; 326 case 'A': 327 if ($hour>=12) $dates .= 'PM'; 328 else $dates .= 'AM'; 329 break; 330 default: 331 $dates .= $format[$i]; break; 332 // ESCAPE 333 case "\\": 334 $i++; 335 if ($i < $max) $dates .= $format[$i]; 336 break; 337 } 338 } 339 return $dates; 340 } 341 342 /** 343 * Low level function to create mktime() for pre-1970 and post 2038 dates. 344 * 345 * @param $hr the hour 346 * @param $min the minute 347 * @param $sec the second 348 * @param $mon the month 349 * @param $day the day 350 * @param $year the year 351 * @param $timezone name 352 * Use 'UTC' to avoid timezone conversion. 353 */ 354 function _date_mktime($hr, $min, $sec, $mon = false, $day = false, $year = false, $timezone = false) { 355 if ($timezone === FALSE) { 356 $timezone = date_default_timezone_name(); 357 } 358 359 /* 360 # disabled because some people place large values in $sec. 361 # however we need it for $mon because we use an array... 362 $hr = intval($hr); 363 $min = intval($min); 364 $sec = intval($sec); 365 */ 366 $mon = intval($mon); 367 $day = intval($day); 368 $year = intval($year); 369 $year = date_year_digit_check($year); 370 if ($mon > 12) { 371 $y = floor(($mon-1) / 12); 372 $year += $y; 373 $mon -= $y * 12; 374 } 375 else if ($mon < 1) { 376 $y = ceil((1-$mon) / 12); 377 $year -= $y; 378 $mon += $y * 12; 379 } 380 $_day_power = 86400; 381 $_hour_power = 3600; 382 $_min_power = 60; 383 $_month_table_normal = array("", 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 384 $_month_table_leap = array("", 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 385 $_total_date = 0; 386 if ($year >= 1970) { 387 $year_in = $year; 388 for ($a = 1970 ; $a <= $year; $a++) { 389 $leap = date_is_leap_year($a); 390 if ($leap == true) { 391 $loop_table = $_month_table_leap; 392 $_add_date = 366; 393 } 394 else { 395 $loop_table = $_month_table_normal; 396 $_add_date = 365; 397 } 398 if ($a < $year) { 399 $_total_date += $_add_date; 400 } 401 else { 402 for ($b=1; $b<$mon; $b++) { 403 $_total_date += $loop_table[$b]; 404 } 405 } 406 } 407 $_total_date +=$day-1; 408 $ret = ($_total_date * $_day_power) + ($hr * $_hour_power) + ($min * $_min_power) + $sec; 409 $ret -= date_get_gmt_diff_ts($ret, $timezone); 410 411 } 412 else { 413 for ($a = 1969 ; $a >= $year; $a--) { 414 $leap = date_is_leap_year($a); 415 if ($leap == true) { 416 $loop_table = $_month_table_leap; 417 $_add_date = 366; 418 } 419 else { 420 $loop_table = $_month_table_normal; 421 $_add_date = 365; 422 } 423 if ($a > $year) { $_total_date += $_add_date; 424 } 425 else { 426 for ($b = 12;$b>$mon;$b--) { 427 $_total_date += $loop_table[$b]; 428 } 429 } 430 } 431 $_total_date += $loop_table[$mon] - $day; 432 $_day_time = $hr * $_hour_power + $min * $_min_power + $sec; 433 $_day_time = $_day_power - $_day_time; 434 $ret = -( $_total_date * $_day_power + $_day_time); 435 if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction 436 else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582. 437 } 438 return $ret; 439 } 440 441 /** 442 * @} End of ingroup "adodb". 443 */
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |