[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/date/date_php4/ -> date_php4_lib.inc (source)

   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   */


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7