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