[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

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

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


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7