[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

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

   1  <?php
   2  
   3  /**
   4   * @file
   5   *
   6   * PHP 5 Date and Timezone function substitutions for PHP 4.
   7   * Replicates some PHP 5 timezone functions and procedures.
   8   * Not all PHP 5 functions have equivalents.
   9   *
  10   * Simpletest tests are provided to use with Simpletest module.
  11   *
  12   * Supported:
  13   *   date_create()
  14   *     with limitations, input date must be one of:
  15   *       - YYYY-MM-DD HH:MM:SS
  16   *       - YYYY-MM-DDTHH:MM:SS
  17   *       - 'now'
  18   *       - unix timestamp prefixed with '@', like '@99999999'
  19   *       - or something strtotime will understand (only for dates later than 1970).
  20   *     also must supply timezone as second argument to date_create().
  21   *   date_modify()
  22   *     with limitations, must supply modification in form like:
  23   *       '+1 day|week|month|year|Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday'
  24   *       '-3 day|week|month|year|Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday'
  25   *   date_format()
  26   *   date_date_set()
  27   *   date_timezone_set()
  28   *   date_offset_get()
  29   *   date_timezone_get()
  30   *   timezone_offset_get()
  31   *   timezone_name_get()
  32   *   timezone_open()
  33   *   timezone_abbreviations_list()
  34   *   timezone_identifiers_list()
  35   *
  36   * Not supported:
  37   *   timezone_ transitions_ get()
  38   *    - we just don't have all those historical transitions available in PHP 4
  39   */
  40  if (!function_exists('date_create')) {
  41  /**
  42   *  PHP 4 equivalent for date_create().
  43   *
  44   *  @param string $date_in
  45   *    - 'now' or empty
  46   *    - anything strtotime will support for a post-1970 date,
  47   *    - a timestamp (must be prefixed with a @ to be interpreted as a
  48   *        timestamp in PHP 5 -- see http://bugs.php.net/bug.php?id=40171)
  49   *    - otherwise, must be a DATETIME date (YYYY-MM-DD HH:MM:SS) or
  50   *        ISO date (YYYY-MM-DDTHH:MM:SS)
  51   *        PHP 5 accepts more alternative formats, but that's too complicated
  52   *        for us to handle here, so a standardized format is required.
  53   *
  54   *  @param string $timezone
  55   *    PHP 5 uses a timezone object, in PHP 4 use a timezone name.
  56   *  @return object
  57   *    Returns and object structured like:
  58   *      Object =>
  59   *        value => '2007-04-15 09:25'
  60   *        timezone => 'UTC'
  61   */
  62    function date_create($date_in = NULL, $timezone = NULL) {
  63      if (empty($date_in) || strtolower($date_in) == 'now') {
  64        // Create a current date for an empty value or 'now'.
  65        $date_out = date_date('Y-m-d H:i:s', (time()), $timezone);
  66      }
  67      elseif (substr($date_in, 0, 1) == '@' && is_numeric(substr($date_in, 1))) {
  68        // An number prefixed with '@' is interpreted as a timestamp.
  69        $date_out = date_date('Y-m-d H:i', substr($date_in, 1), $timezone);
  70      }
  71      elseif (preg_match(DATE_REGEX_LOOSE, $date_in, $regs)) {
  72        $year = date_pad(isset($regs[1]) ? $regs[1] : 0, 4);
  73        $month = date_pad(isset($regs[2]) ? $regs[2] : 0);
  74        $day = date_pad(isset($regs[3]) ? $regs[3] : 0);
  75        $hour = date_pad(isset($regs[5]) ? $regs[5] : 0);
  76        $minute = date_pad(isset($regs[6]) ? $regs[6] : 0);
  77        $second = date_pad(isset($regs[7]) ? $regs[7] : 0);
  78        $date_out = "$year-$month-$day $hour:$minute:$second";
  79      }
  80      else {
  81        // Try to use strtotime, will only work on post-1970 dates.
  82        // Only use it if the value is big enough that timezone conversions
  83        // won't make it into a negative value.
  84        $test = @strtotime($date_in .' '. $timezone);
  85        if ($test > 86400) {
  86          $date_out = date_date('Y-m-d H:i', $test, $timezone);
  87        }
  88      }
  89      if (empty($date_out)) {
  90        return NULL;
  91      }
  92      $date = new StdClass();
  93      $date->value = $date_out;
  94      $date->timestamp = date_datetime2timestamp($date->value, $timezone);
  95      $date->timezone = $timezone;
  96      return $date;
  97    }
  98  }
  99  
 100  if (!function_exists('date_format')) {
 101    require_once('./'. drupal_get_path('module', 'date_php4') .'/date_php4_calc.inc');
 102  /**
 103   * PHP 4 equivalent for date_format().
 104   *
 105   * Some formats that work in PHP 5 won't work in PHP 4, many won't work for
 106   * dates earlier than 1970. Filter out those that need special treatment.
 107   * No translation done here because the PHP 5 date_format() function isn't
 108   * doing any translation and we need to return identical values in both.
 109   *
 110   * @param object $date
 111   * @param string $format
 112   * @return string
 113   *   return formatted date
 114   */
 115    function date_format($date, $format) {
 116      $php5_formats = array('N', 'o', 'e', 'P', 'c', '\\');
 117      $timestamp = $date->timestamp;
 118      $date_string = '';
 119      $max = strlen($format);
 120      for ($i = 0; $i < $max; $i++) {
 121        $c = $format[$i];
 122        if ($date->timezone == 'UTC' && abs($timestamp) <= 0x7FFFFFFF && !in_array($c, $php5_formats)) {
 123          $date_string .= gmdate($c, $timestamp);
 124        }
 125        else{
 126          switch ($c) {
 127            case 'U':
 128              $date_string .= $timestamp;
 129              break;
 130            case 'l':
 131            case 'w':
 132            case 'D':
 133              $dow = date_dow(date_part_extract($date->value, 'day'),
 134                date_part_extract($date->value, 'month'),
 135                date_part_extract($date->value, 'year'));
 136              if ($c == 'w') {
 137                $date_string .= $dow;
 138              }
 139              elseif ($c == 'l') {
 140                $days = date_week_days_untranslated();
 141                $date_string .= $days[$dow];
 142              }
 143              elseif ($c == 'D') {
 144                // There is no date_week_days_abbr_untranslated(). 
 145                // This rule works for English, untranslated day names.
 146                $days = date_week_days_abbr();
 147                $date_string .= substr($days[$dow], 0, 3);
 148              }
 149              break;
 150            case 'L':
 151              $date_string .= date_is_leap_year(date_part_extract($date->value, 'year'));
 152              break;
 153            case 'z':
 154              $date_string .= date_calc_julian_date(date_part_extract($date->value, 'day'),
 155              date_part_extract($date->value, 'month'),
 156              date_part_extract($date->value, 'year'));
 157              break;
 158            case 'N':
 159              $w = date_date('w', $timestamp, $date->timezone);
 160              $date_string .= $w != 0 ? $w : 7;
 161              break;
 162            case 'o':
 163              $iso_week = date_calc_gregorian_to_ISO(date_part_extract($date->value, 'day'),
 164                date_part_extract($date->value, 'month'),
 165                date_part_extract($date->value, 'year'));
 166              $iso = explode('-', $iso_week);
 167              $date_string .= ($c == 'o') ? $iso[0] : $iso[1];
 168              break;
 169            case 'O':
 170              $date_string .= sprintf('%s%02d%02d', (date_offset_get($date) < 0 ? '-' : '+'), abs(date_offset_get($date) / 3600), abs(date_offset_get($date) % 3600) / 60);
 171              break;
 172            case 'P':
 173              $date_string .= sprintf('%s%02d:%02d', (date_offset_get($date) < 0 ? '-' : '+'), abs(date_offset_get($date) / 3600), abs(date_offset_get($date) % 3600) / 60);
 174              break;
 175            case 'e':
 176              $date_string .= $date->timezone;
 177              break;
 178            case 'Z':
 179              $date_string .= date_offset_get($date);
 180              break;
 181            case '\\':
 182              $date_string .= $format[++$i];
 183              break;
 184            case 't':
 185              $date_string .= date_calc_days_in_month(date_part_extract($date->value, 'month'),
 186                date_part_extract($date->value, 'year'));
 187              break;
 188            case 'W':
 189              $result = date_calc_gregorian_to_ISO(date_part_extract($date->value, 'day'),
 190                date_part_extract($date->value, 'month'),
 191                date_part_extract($date->value, 'year'));
 192              $result = explode('-', $result);  
 193              $date_string .= $result[1];  
 194            default:
 195              if (strpos('AaeDFlMTBcdGgHhIijLmNnOoPrSstUuwYyZz', $c) !== FALSE) {
 196                $date_string .= date_date($c, $timestamp, $date->timezone);
 197              }
 198              else {
 199                $date_string .= $c;
 200              }
 201          }
 202        }
 203      }
 204      return $date_string;
 205    }
 206  }
 207  
 208  /**
 209   *  PHP 4 equivalent for date_date_set().
 210   *
 211   *  @param $date
 212   *    a date object returned by date_create().
 213   *  @param $year
 214   *    a new year.
 215   *  @param $month
 216   *    a new month.
 217   *  @param $day
 218   *    a new day.
 219   *  @return $date
 220   *    the date objected updated for the new timezone.
 221   *
 222   */
 223  if (!function_exists('date_date_set')) {
 224    function date_date_set(&$date, $year, $month, $day) {
 225      $new_date = substr_replace($date->value, date_pad($year, 4), 0, 4);
 226      $new_date = substr_replace($new_date, date_pad($month), 5, 2);
 227      $new_date = substr_replace($new_date, date_pad($day), 8, 2);
 228      $date = date_create($new_date, $date->timezone);
 229      return $date;
 230    }
 231  }
 232  
 233  /**
 234   *  PHP 4 equivalent for date_date_set().
 235   *
 236   *  @param $date
 237   *    a date object returned by date_create().
 238   *  @param $year
 239   *    a new year.
 240   *  @param $month
 241   *    a new month.
 242   *  @param $day
 243   *    a new day.
 244   *  @return $date
 245   *    the date objected updated for the new timezone.
 246   *
 247   */
 248  if (!function_exists('date_time_set')) {
 249    function date_time_set(&$date, $hour, $minute, $second) {
 250      $new_date = substr_replace($date->value, date_pad($hour), 11, 2);
 251      $new_date = substr_replace($new_date, date_pad($minute), 14, 2);
 252      $new_date = substr_replace($new_date, date_pad($second), 16, 2);
 253      $date = date_create($new_date, $date->timezone);
 254      return $date;
 255    }
 256  }
 257  
 258  if (!function_exists('date_timezone_set')) {
 259  /**
 260   *  PHP 4 equivalent for date_timezones_set().
 261   *
 262   *  @param $date
 263   *    a date object returned by date_create().
 264   *  @param $timezone
 265   *    a new timezone for the date object.
 266   *  @return $date
 267   *    the date objected updated for the new timezone.
 268   *
 269   */
 270    function date_timezone_set(&$date, $timezone) {
 271      $date->timezone = $timezone;
 272      $date->value = date_date(DATE_FORMAT_DATETIME, $date->timestamp, $timezone);
 273      return $date;
 274    }
 275  }
 276  
 277  if (!function_exists('timezone_open')) {
 278  /**
 279   *  PHP 4 equivalent for timezone_open().
 280   *   Just track the timezone name.
 281   */
 282    function timezone_open($timezone) {
 283      return $timezone;
 284    }
 285  }
 286  
 287  if (!function_exists('timezone_name_get')) {
 288  /**
 289   *  PHP 4 equivalent for timezone_name_get().
 290   */
 291    function timezone_name_get($timezone) {
 292      return $timezone;
 293    }
 294  }
 295  
 296  if (!function_exists('date_timezone_get')) {
 297  /**
 298   *  PHP 4 equivalent for date_timezone_get().
 299   */
 300    function date_timezone_get($date) {
 301      return $date->timezone;
 302    }
 303  }
 304  
 305  if (!function_exists('timezone_offset_get')) {
 306  /**
 307   *  PHP 4 equivalent for timezone_offset_get().
 308   *
 309   *  Cache results for expensive process of getting offsets for each timezone.
 310   *  Each cached timezone array will show whether the timezone has dst and the
 311   *  dst and non-dst offset for that timezone.
 312   *
 313   *  @param $timezone
 314   *    a timezone returned by timezone_open().
 315   *  @param $date
 316   *    a date object returned by date_create().
 317   *  @return $offset
 318   *    the offset in seconds for the supplied date object.
 319   */
 320    function timezone_offset_get($timezone, $date) {
 321      if (empty($timezone) || $timezone == 'UTC' || !date_timezone_is_valid($timezone)) {
 322        return 0;
 323      }
 324      static $zones = array(), $offsets = array();
 325      if (!in_array($timezone, $zones)) {
 326        $cached = cache_get('date_timezone_offsets:'. $timezone);
 327        $offsets[$timezone] = isset($cached->data) ? $cached->data : array();
 328        $zones[] = $timezone;
 329        if (empty($offsets[$timezone])) {
 330          $offsets[$timezone] = array('dst' => 0);
 331          $zones = timezone_abbreviations_list();
 332          foreach ($zones as $key => $abbr) {
 333            foreach ($abbr as $zone) {
 334              if ($zone['timezone_id'] == $timezone && $zone['dst'] == 1 && !isset($offsets[$timezone]['dst_offset'])) {
 335                $offsets[$timezone]['dst_offset'] = $zone['offset'];
 336                $offsets[$timezone]['dst'] = 1;
 337              }
 338              elseif ($zone['timezone_id'] == $timezone && $zone['dst'] != 1 && !isset($offsets[$timezone]['offset'])) {
 339                $offsets[$timezone]['offset'] = $zone['offset'];
 340              }
 341            }
 342          }
 343          cache_set('date_timezone_offsets:'. $timezone, $offsets[$timezone]);
 344        }
 345      }
 346      $timestamp = $date->timestamp;
 347      if ($offsets[$timezone]['dst'] == 1) {
 348        if (date_is_dst($timestamp, $timezone, $offsets[$timezone]['dst'])) {
 349          return $offsets[$timezone]['dst_offset'];
 350        }
 351      }
 352      return $offsets[$timezone]['offset'];
 353    }
 354  }
 355  
 356  if (!function_exists('date_offset_get')) {
 357  /**
 358   *  PHP 4 equivalent for date_offset_get().
 359   *
 360   *  Cache results for expensive process of getting offsets for each timezone.
 361   *  Each cached timezone array will show whether the timezone has dst and the
 362   *  dst and non-dst offset for that timezone.
 363   *
 364   *  @param $date
 365   *    a date object returned by date_create().
 366   *  @return $offset
 367   *    the offset in seconds for the supplied date object.
 368   */
 369    function date_offset_get($date) {
 370      return timezone_offset_get(timezone_open($date->timezone), $date);
 371    }
 372  }
 373  
 374  if (!function_exists('date_modify')) {
 375    require_once('./'. drupal_get_path('module', 'date_php4') .'/date_php4_calc.inc');
 376  /**
 377   * A limited set of options are provided here to modify dates.
 378   * Uses strtotime() on dates after 1970. Uses date_php4_calc.inc to do
 379   * calculations on older dates.
 380   *
 381   * Will work for things like date_modify($date, '+1 Sunday');
 382   *
 383   * @param $date
 384   *   a date object created by date_create() to use as a reference
 385   *   point for the calculation.
 386   * @param $change
 387   *   something like following phrases:
 388   *     '+1 day|week|month|year|Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday'
 389   *     '-3 day|week|month|year|Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday'
 390   *
 391   * @return
 392   *   the date that matches the phrase.
 393   *
 394   */
 395    function date_modify(&$date, $change) { 
 396      $cdate = $date->value;
 397      $time = substr($date->value, 11, 8);
 398  
 399      // We have to use strings like 'First Sunday' instead of
 400      // +1 Sunday to overcome a PHP5 bug (see #369020).
 401      // Swap those values out here and go back to '+1 Sunday',
 402      // the code that works in PHP4.
 403      $replace = array_flip(date_order());
 404      $change = strtr($change, $replace);
 405  
 406      $change = trim($change);   
 407      //Date is too old for strtotime(), or looking for custom +/- values, use date_calc instead.
 408      if (substr($change, 0, 1) != '+' && substr($change, 0, 1) != '-'
 409      && 1971 < date_part_extract($cdate, 'year')
 410      && date_part_extract($cdate, 'year') < 2038) {
 411        $cdate = strtotime($change, strtotime($cdate .' UTC'));
 412        // strtotime will sometimes end up with a bogus adjustment for daylight
 413        // savings time, so compute the date and force them time back to the original.
 414        $date->value = substr_replace(date_date(DATE_FORMAT_DATETIME, $cdate, $date->timezone), $time, 11);
 415      }
 416      else {
 417        $days = date_week_days_untranslated();
 418        $dows = array_flip($days);
 419        preg_match('/([+|-])\s?([0-9]{1,32})\s?([day(s)?|week(s)?|month(s)?|year(s)?|hour(s)?|minute(s)?|second(s)?|Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday]{1,10})/', $change, $results);
 420        $direction = $results[1];
 421        $count = $results[2];
 422        $item = $results[3];
 423        if (empty($results) || empty($item)) {
 424          return;
 425        }
 426        if (substr($item, -1) == 's') {
 427          $item = substr($item, 0, strlen($item) - 1);
 428        }
 429        // Process +/- Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday
 430        if (in_array($item, $days)) {
 431          $dow = $dows[$item];
 432          if ($direction == '+') {
 433            $function = 'date_calc_next_day_of_week';
 434          }
 435          else {
 436            $function = 'date_calc_prev_day_of_week';
 437          }
 438          for ($i = 1; $i <= $count; $i++) {
 439            $cdate = $function($dow,
 440              date_part_extract($cdate, 'day'),
 441              date_part_extract($cdate, 'month'),
 442              date_part_extract($cdate, 'year'));
 443          }
 444          $date->value = $cdate .' '. $time;
 445        }
 446        elseif ($item == 'day') {
 447          if ($direction == '+') {
 448            $function = 'date_calc_next_day';
 449          }
 450          else {
 451            $function = 'date_calc_prev_day';
 452          }
 453          for ($i = 1; $i <= $count; $i++) {
 454            $cdate = $function(date_part_extract($cdate, 'day'),
 455              date_part_extract($cdate, 'month'),
 456              date_part_extract($cdate, 'year'));
 457          }
 458          $date->value = $cdate .' '. $time;
 459        }
 460        elseif ($item == 'month') {
 461          if ($direction == '+') {
 462            $function = 'date_calc_begin_of_month_by_span';
 463          }
 464          else {
 465            $function = 'date_calc_end_of_month_by_span';
 466          }
 467          // Find the next end or beginning of month that matches the search.
 468          $day = date_part_extract($cdate, 'day');
 469          $cdate = $function($direction . $count, date_part_extract($cdate, 'month'), date_part_extract($cdate, 'year'));
 470          // Construct a new date with the current day of the month and the new month and year.
 471          $mon = date_part_extract($cdate, 'month');
 472          $year = date_part_extract($cdate, 'year');
 473          $date->value = date_pad($year, 4) .'-'. date_pad($mon) .'-'. date_pad($day) .' '. $time;
 474        }
 475        elseif ($item == 'week') {
 476          $dow = date_day_of_week($date);
 477          if ($direction == '+') {
 478            $function = 'date_calc_begin_of_next_week';
 479          }
 480          else {
 481            $function = 'date_calc_begin_of_prev_week';
 482          }
 483          // Move to right week.
 484          for ($i = 1; $i <= $count; $i++) {
 485            $cdate = $function(date_part_extract($cdate, 'day'),
 486              date_part_extract($cdate, 'month'),
 487              date_part_extract($cdate, 'year'));
 488          }
 489          // Move to the right day of the week, if we're not looking for the first day.
 490          if ($dow != variable_get('date_first_day', 1)) {
 491            for ($i = 1; $i <= $dow; $i++) {
 492              $cdate = date_calc_next_day(date_part_extract($cdate, 'day'),
 493                date_part_extract($cdate, 'month'),
 494                date_part_extract($cdate, 'year'));
 495            }
 496          }
 497          $date->value = $cdate .' '. $time;
 498        }
 499        elseif ($item == 'year') {
 500          // Move to the new year.
 501          $year = date_part_extract($cdate, 'year');
 502          for ($i = 1; $i <= $count; $i++) {
 503            if ($direction == '+') {
 504              $year++;
 505            }
 506            else {
 507              $year--;
 508            }
 509          }
 510          // Construct a new date with the current day and month and the new year.
 511          $day = date_part_extract($cdate, 'day');
 512          $mon = date_part_extract($cdate, 'month');
 513          $date->value = date_pad($year, 4) .'-'. date_pad($mon) .'-'. date_pad($day) .' '. $time;
 514        }
 515        else {
 516          switch ($item) {
 517            case 'hour':
 518              $count = $count * 3600;
 519              break;
 520            case 'minute':
 521              $count = $count * 60;
 522              break;
 523          }
 524          switch ($direction) {
 525            case '-':
 526              $timestamp = $date->timestamp - $count;
 527              break;
 528            default:
 529              $timestamp = $date->timestamp + $count;
 530          }
 531          $date->value = date_date('Y-m-d H:i:s', $timestamp, $date->timezone);
 532        }
 533      }
 534      $date->timestamp = date_datetime2timestamp($date->value, $date->timezone);
 535      return $date;
 536    }
 537  }
 538  
 539  if (!function_exists('timezone_identifiers_list')) {
 540  /**
 541   * PHP 4 equivalent for timezone_identifiers_list().
 542   *
 543   * Expanded array looks like:
 544   * array(
 545   *   0 => 'Africa/Abidjan',
 546   *   1 => 'Africa/Accra',
 547   *   2 => 'Africa/Addis_Ababa',
 548   *   ...
 549   */
 550    function timezone_identifiers_list() {
 551      static $timezone_identifiers_list = array();
 552      if (empty($timezone_identifiers_list)) {
 553        include(drupal_get_path('module', 'date_php4') .'/date_php4_tz_identifiers.inc');
 554      }
 555      return $timezone_identifiers_list;
 556    }
 557  }
 558  
 559  if (!function_exists('timezone_abbreviations_list')) {
 560  /**
 561   * PHP 4 equivalent for timezone_abbreviations_list().
 562   *   Array keyed on timezone abbreviation.
 563   *
 564   * Expanded array looks like:
 565   * array(
 566   *   'cdt' => array (
 567   *     0 => array (
 568   *      'dst' => true,
 569   *      'offset' => -18000,
 570   *      'timezone_id' => 'America/Chicago',
 571   *     ),
 572   *     1 => array (
 573   *      'dst' => true,
 574   *      'offset' => -14400,
 575   *      'timezone_id' => 'America/Havana',
 576   *     )...
 577   *
 578   */
 579    function timezone_abbreviations_list() {
 580      static $timezone_abbreviations_list = array();
 581      if (empty($timezone_abbreviations_list)) {
 582        include(drupal_get_path('module', 'date_php4') .'/date_php4_tz_abbreviations_list.inc');
 583      }
 584      return $timezone_abbreviations_list;
 585    }
 586  }
 587  
 588  /**
 589   * Create a timestamp from a datetime value.
 590   *
 591   * Can't use date_convert() to turn datetime to unix within the
 592   * PHP 4 emulation  because it creates endless loops.
 593   */
 594  function date_datetime2timestamp($datetime, $timezone) {
 595    preg_match(DATE_REGEX_LOOSE, $datetime, $regs);
 596    return date_mktime((isset($regs[5]) ? $regs[5] : 0), (isset($regs[6]) ? $regs[6] : 0), (isset($regs[7]) ? $regs[7] : 0), (isset($regs[2]) ? $regs[2] : 0), (isset($regs[3]) ? $regs[3] : 0), (isset($regs[1]) ? $regs[1] : 0), $timezone);
 597  }
 598  
 599  /**
 600   * Check if time is in Daylight Savings Time
 601   *   Uses dst region code, as stored in the $timezone_map array
 602   *   from date_php4_tz_map.inc
 603   *
 604   * @param $timezone name
 605   * @param $timestamp
 606   * @return
 607   *   0 or 1
 608   */
 609  function date_is_dst($timestamp, $timezone = NULL) {
 610    if (abs($timestamp) > 0x7FFFFFFF) {
 611      return FALSE;
 612    }
 613    if (empty($timezone)) {
 614      $timezone = date_default_timezone_name();
 615    }
 616  
 617    static $timezone_map = array();
 618    if (empty($timezone_map)) {
 619      include(drupal_get_path('module', 'date_php4') .'/date_php4_tz_map.inc');
 620    }
 621    $region = array_key_exists($timezone, $timezone_map) ? $timezone_map[$timezone]['dst_region'] : 0;
 622  
 623    // This should really be done with date_date() to get the right timezone
 624    // adjustment for the year, but that leads to circular code that won't
 625    // work, so we're stuck with date(), which hopefully will create the right
 626    // year in most cases.
 627    $year = date('Y', $timestamp);
 628  
 629    // Information on Daylight Saving time was obtained from http://webexhibits.org/daylightsaving/g.html
 630    // Note that 'last sunday' is interpreted as 'the last sunday before...'.
 631    switch ($region) {
 632      case 0:
 633        return 0;
 634      case 1: // Egypt
 635        // start of DST (last Friday in April)
 636        $dststart = strtotime("last friday UTC", strtotime("1 may $year UTC"));
 637        // end of DST (last Thursday in September)
 638        $dstend = strtotime("last thursday UTC", strtotime("1 october $year UTC"));
 639        break;
 640      case 2: // Namibia
 641        // start of DST (first Sunday in September)
 642        $dststart = strtotime("first sunday UTC", strtotime("1 september $year UTC"));
 643        // end of DST (first Sunday April)
 644        $dstend = strtotime("first sunday UTC", strtotime("1 april $year UTC"));
 645        break;
 646      case 3: // Former USSR
 647        // start of DST (last Sunday in March)
 648        $dststart = strtotime("last sunday UTC", strtotime("1 april $year UTC"));
 649        // end of DST (last Sunday October)
 650        $dstend = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 651        break;
 652      case 4: // Iraq, Syria
 653        // start of DST (April 1st)
 654        $dststart = strtotime("1 april $year UTC");
 655        // end of DST (October 1st)
 656        $dstend = strtotime("1 october $year UTC");
 657        break;
 658      case 5: // Israel
 659        // start of DST (last Friday befor April 2nd, 2am)
 660        $dststart = strtotime("-1 week friday GMT", strtotime("2 april $year GMT")) + 7200;
 661        // end of DST (last sunday before 10th of tishray. see http://cgate.co.il/navigation/shaon_kaiz.htm.
 662        switch ($year) {
 663          case '2007':
 664            $dstend = strtotime("-1 sunday GMT", strtotime("16 september $year GMT"))+ 7200;
 665            break;
 666          case '2008':
 667            $dstend = strtotime("-1 sunday GMT",strtotime("9 october $year GMT"))+7200;
 668            break;
 669          case '2009':
 670            $dstend = strtotime("-1 sunday GMT", strtotime("28 september $year GMT"))+ 7200;
 671            break;
 672          case '2010':
 673            $dstend = strtotime("-1 sunday GMT", strtotime("18 september $year GMT"))+ 7200;
 674            break;
 675          case '2011':
 676            $dstend = strtotime("-1 sunday GMT", strtotime("8 october $year GMT"))+ 7200;
 677            break;
 678          case '2012':
 679            $dstend = strtotime("-1 sunday GMT", strtotime("26 september $year GMT"))+ 7200;
 680            break;
 681          case '2013':
 682            $dstend = strtotime("-1 sunday GMT", strtotime("14 september $year GMT"))+ 7200;
 683            break;
 684          case '2014':
 685            $dstend = strtotime("-1 sunday GMT", strtotime("4 october $year GMT"))+ 7200;
 686            break;
 687          case '2015':
 688            $dstend = strtotime("-1 sunday GMT", strtotime("23 september $year GMT"))+ 7200;
 689            break;
 690          case '2016':
 691            $dstend = strtotime("-1 sunday GMT", strtotime("12 october $year GMT"))+ 7200;
 692            break;
 693          default:
 694            return false;
 695        }
 696        break;
 697      case 6: // Lebanon, Kirgizstan
 698        // start of DST (Last Sunday in March)
 699        $dststart = strtotime("last sunday UTC", strtotime("1 april $year UTC"));
 700        // end of DST (Last Sunday in October)
 701        $dstend = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 702        break;
 703      case 7: // Palestine
 704        // start of DST (First Friday on or after April 15th)
 705        $dststart = strtotime("next friday UTC", strtotime("14 april $year UTC"));
 706        // end of DST (First Friday on or after October 15th)
 707        $dstend = strtotime("next friday UTC", strtotime("14 october $year UTC"));
 708        break;
 709      case 8: // Iran
 710        // start of DST (the first day of Farvardin (March 21))
 711        $dststart = strtotime("21 march $year UTC");
 712        // end of DST (the first day of Mehr (September 23))
 713        $dstend = strtotime("23 september $year UTC");
 714        break;
 715      case 9: // South Australia
 716        // start of DST  (last Sunday in October)
 717        $dststart = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 718        // end of DST (last Sunday in March)
 719        $dstend = strtotime("last sunday UTC", strtotime("1 april $year UTC"));
 720        break;
 721      case 10: // Australia, Tasmania
 722        // start of DST  (first Sunday in October)
 723        $dststart = strtotime("first sunday UTC", strtotime("1 october $year UTC"));
 724        // end of DST (last Sunday in March)
 725        $dstend = strtotime("last sunday UTC", strtotime("1 april $year UTC"));
 726        break;
 727      case 11: // New Zealand
 728        // start of DST  (first Sunday in October)
 729        $dststart = strtotime("first sunday UTC", strtotime("1 october $year UTC"));
 730        // end of DST (first Sunday in April)
 731        $dstend = strtotime("first sunday UTC", strtotime("1 april $year UTC"));
 732        break;
 733      case 12: // Tonga
 734        // start of DST (first Sunday in November)
 735        $dststart = strtotime("first sunday UTC",  strtotime("1 november $year UTC"));
 736        // end of DST (last Sunday in January)
 737        $dstend = strtotime("last sunday UTC", strtotime("1 february $year UTC"));
 738        break;
 739      case 13: // EU and other European countries
 740        // start of DST (last Sunday in March 1 am UTC)
 741        $dststart = strtotime("last sunday UTC", strtotime("1 april $year UTC"));
 742        // end of DST in Europe (last Sunday in October 1 am UTC)
 743        $dstend = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 744        break;
 745      case 14: // Russian Federation
 746        // start of DST (last Sunday in March 2 am local time)
 747        $dststart = strtotime("last sunday UTC", strtotime("1 april $year UTC"));
 748        // end of DST (last Sunday in October 2 am local time)
 749        $dstend = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 750        break;
 751      case 15: // Northern America (where applicable)
 752        // start of DST  (where applicable) (first Sunday in April before 2007,
 753        // after that second Sunday in March, 2 am local time)
 754        if ($year < 2007) {
 755          $dststart = strtotime("first sunday UTC", strtotime("1 april $year UTC"));
 756        }
 757        else {
 758          $dststart = strtotime("second sunday UTC", strtotime("1 march $year UTC"));
 759        }
 760        // end of DST (where applicable) (last Sunday in October 2 am local time)
 761        if ($year < 2007) {
 762          $dstend = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 763        }
 764        else {
 765          $dstend = strtotime("first sunday UTC", strtotime("1 november $year UTC"));
 766        }
 767        break;
 768      case 16: // Cuba
 769        // start of DST  (April 1st)
 770        $dststart = strtotime("1 april $year UTC");
 771        // end of DST (last Sunday in October)
 772        $dstend = strtotime("last sunday UTC", strtotime("1 november $year UTC"));
 773        break;
 774      case 17: // Brazil
 775        // start of DST  (first Sunday in November)
 776        $dststart = strtotime("first sunday UTC", strtotime("1 november $year UTC"));
 777        // end of DST (third Sunday in February)
 778        $dstend = strtotime("third sunday UTC", strtotime("1 february $year UTC"));
 779        break;
 780      case 18: // Chile
 781        // start of DST  (Second Saturday of October - at midnight)
 782        $dststart = strtotime("second saturday UTC", strtotime("1 october $year UTC"));
 783        // end of DST (Second Saturday of March - at midnight)
 784        $dstend = strtotime("second sunday UTC", strtotime("1 march $year UTC"));
 785        break;
 786      case 19: // Falklands
 787        // start of DST  (First Sunday on or after 8 September)
 788        $dststart = strtotime("next sunday UTC", strtotime("7 september $year UTC"));
 789        // end of DST (First Sunday on or after 6 April)
 790        $dstend = strtotime("next sunday UTC", strtotime("5 april $year UTC"));
 791        break;
 792      case 20: // Paraguay
 793        // start of DST  (first Sunday in September)
 794        $dststart = strtotime("first sunday UTC", strtotime("1 september $year UTC"));
 795        // end of DST (first Sunday in April)
 796        $dstend = strtotime("first sunday UTC", strtotime("1 april $year UTC"));
 797        break;
 798    }
 799    // Have to use reverse logic in southern hemisphere.
 800    $southern = array(9, 10, 11, 12, 17, 18, 19, 20);
 801    if (in_array($region, $southern)) {
 802      return !($timestamp <= $dststart && $dstend <= $timestamp);
 803    }
 804    else {
 805      return ($dststart <= $timestamp && $timestamp <= $dstend);
 806    }
 807  }
 808  
 809  /**
 810   * @ingroup adodb
 811   * @{
 812   */
 813  /**
 814   * Functions to handle mktime(), date(), and getdate() for dates outside the
 815   * normal range. Uses native php date functions when possible, alterate
 816   * methods when native functions won't work.
 817   *
 818   * Without these functions date(), mktime(), and getdate() won't work on
 819   * dates prior to 1970 in PHP 4 or on dates prior to 1901 in PHP 5.
 820   *
 821   * Replace native php functions:
 822   *   getdate() with date_getdate()
 823   *   date() with date_date()
 824   *   gmdate() with date_gmdate()
 825   *   mktime() with date_mktime()
 826   *   gmmktime() with gmdate_mktime()
 827   *
 828   * Note: Dates earlier than 1582 need a Gregorian correction applied, which
 829   * works correctly if only applied once. If the same early date is run through
 830   * these functions more than once, the Gregorian correction may get duplicated
 831   * or undone and not work correctly.
 832   *
 833   * The solution in PHP 5 is to use date_create() and date_format() for very old
 834   * dates, which will correctly handle that adjustment. There is no foolproof
 835   * workaround for PHP 4. PHP 5 date_create() and date_format() functions
 836   * will also handle dates earlier than 100.
 837   *
 838   * The following functions were derived from code obtained from
 839   * http://phplens.com/phpeverywhere/adodb_date_library, licensed as follows:
 840   *
 841   * COPYRIGHT(c) 2003-2005 John Lim
 842   * All rights reserved.
 843   *
 844   * Redistribution and use in source and binary forms, with or without
 845   * modification, are permitted under the terms of the BSD License.
 846   *
 847   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 848   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 849   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 850   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 851   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 852   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 853   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 854   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 855   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 856   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 857   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 858   * POSSIBILITY OF SUCH DAMAGE.
 859  */
 860  
 861  require_once('./'. drupal_get_path('module', 'date_php4') .'/date_php4_lib.inc');
 862  
 863  /**
 864   * Returns an array with date info.
 865   *
 866   * @param $timestamp
 867   *   A unix timestamp.
 868   * @param $timezone name
 869   *   Use 'UTC' to avoid timezone conversion.
 870   */
 871  function date_getdate($timestamp = false, $timezone = false) {
 872    return _date_getdate($timestamp, $timezone);
 873  }
 874  
 875  /**
 876   * Like date_getdate with no GMT conversion.
 877   */
 878  function date_gmgetdate($timestamp = false) {
 879    if (!$timestamp) return array();
 880    $array    = date_getdate($timestamp, 'UTC');
 881    $array[0] = $timestamp;
 882    return $array;
 883  }
 884  
 885  /**
 886   * Return formatted date based on timestamp $timestamp.
 887   *
 888   * @param $format
 889   *   the format to be used for the returned timestamp
 890   * @param $timestamp
 891   *   a unix timestamp
 892   * @param $timezone name
 893   *   Use 'UTC' to avoid timezone conversion.
 894   */
 895  function date_date($format, $timestamp = false, $timezone = false) {
 896    // date($format) will adjust to the server timezone, which may
 897    // not be right, but we don't use it in this module anywhere and 
 898    // there is no easy way to get it working right without creating 
 899    // circular code.
 900    if ($timestamp === false) return ($is_gmt)? @gmdate($format): @date($format);
 901    if ($timezone === FALSE) {
 902      $timezone = date_default_timezone_name();
 903    }
 904    // Anything with a timezone other than UTC needs to be forced to the
 905    // low level function to compute the timezone offset correctly.
 906    $is_gmt = $timezone == 'UTC' ? TRUE : FALSE;
 907    if (abs($timestamp) <= 0x7FFFFFFF) {
 908      // Below PHP 5.2 in windows, must be positive integer
 909      if ($timestamp >= 0 && $is_gmt) {
 910        return @gmdate($format, $timestamp);
 911      }
 912      elseif ($timestamp >= 0 && variable_get('date_use_server_zone', FALSE)) {
 913        return @date($format, $timestamp);
 914      }
 915    }
 916    return _date_date($format, $timestamp, $timezone);
 917  }
 918  
 919  /**
 920   * Like date_date with no GMT conversion.
 921   */
 922  function date_gmdate($format, $timestamp = false, $test = false) {
 923    return date_date($format, $timestamp, 'UTC', $test);
 924  }
 925  
 926  /**
 927   * Return a timestamp given a local time.
 928   * 
 929   * @param $timezone name
 930   *   Use 'UTC' to avoid timezone conversion.
 931   *
 932   * Force anything that will require timezone conversion to use
 933   * lower level functions to make sure we adjust to the right timezone
 934   * (native 'date' functions use the server timezone).
 935   */
 936  function date_mktime($hr, $min, $sec, $mon = false, $day = false, $year = false, $timezone = false) {
 937    if ($timezone === FALSE) {
 938      $timezone = date_default_timezone_name();
 939    }
 940    $is_gmt = $timezone == 'UTC' ? TRUE : FALSE;
 941    $hr = intval($hr);
 942    $min = intval($min);
 943    $sec = intval($sec);
 944    if ($mon === false && $is_gmt) {
 945      return @gmmktime($hr, $min, $sec);
 946    }
 947    $mon = intval($mon) > 0 ? intval($mon) : date('n');
 948    $day = intval($day) > 0 ? intval($day) : date('j');
 949    $year = intval($year) > 0 ? intval($year) : date('Y');
 950  
 951    // Don't use native handling for any values that could create negative
 952    // timestamp, Windows does not support them at all in PHP 4, and
 953    // the adodb date library notes that since RedHat 7.3, negative 
 954    // timestamps are not supported in glibc either.
 955    // Step in one year on either side of allowable 1970-2038 window
 956    // to be sure timezone adjustments and month and day additions
 957    // won't push our date outside this window.
 958    if (1971 < $year && $year < 2037 && $is_gmt) {
 959      return @gmmktime($hr, $min, $sec, $mon, $day, $year);
 960    }
 961  
 962    return _date_mktime($hr, $min, $sec, $mon, $day, $year, $timezone);
 963  }
 964  
 965  /**
 966   * Like date_mktime with no GMT conversion.
 967  */
 968  function date_gmmktime($hr, $min, $sec, $mon = false, $day = false, $year = false) {
 969    return date_mktime($hr, $min, $sec, $mon, $day, $year, 'UTC');
 970  }
 971  
 972  /**
 973   * Get local time zone offset from GMT.
 974   * 
 975   * @return timezone offset in seconds
 976   */
 977  function date_get_gmt_diff_ts($timestamp, $timezone = NULL) {
 978    if ($timezone == 'UTC') {
 979      return 0;
 980    }
 981    elseif (empty($timezone)) {
 982      $timezone = date_default_timezone_name();
 983    }
 984    $date = new StdClass();
 985    $date->timestamp = $timestamp;
 986    $date->timezone = $timezone;
 987    return date_offset_get($date);
 988  }
 989  
 990  /**
 991   * Fix 2-digit years. Works for any century. Assumes that if 2-digit is
 992   * more than 30 years in future, then previous century.
 993  */
 994  function date_year_digit_check($y) {
 995    if ($y < 100) {
 996      $yr = (integer) date("Y");
 997      $century = (integer) ($yr /100);
 998      if ($yr%100 > 50) {
 999        $c1 = $century + 1;
1000        $c0 = $century;
1001      } else {
1002        $c1 = $century;
1003        $c0 = $century - 1;
1004      }
1005      $c1 *= 100;
1006      // if 2-digit year is less than 30 years in future, set it to this century
1007      // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
1008      if (($y + $c1) < $yr + 30) $y = $y + $c1;
1009      else $y = $y + $c0 * 100;
1010    }
1011    return $y;
1012  }
1013  
1014  /**
1015   * Returns day of week for given date (0 = Sunday), works on dates outside
1016   * normal date range.
1017   *
1018   * Adapted from a function in the ADODB date library by John Lim, more info in
1019   * date_php4_lib.inc.
1020   *
1021   * @param int  $day
1022   * @param int  $month
1023   * @param int  $year
1024   * @return
1025   *    the number of the day in the week
1026   */
1027  function date_dow($day, $month, $year) {
1028    // Gregorian correction from ADODB
1029    if ($year <= 1582) {
1030      if ($year < 1582 ||
1031        ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
1032       else
1033        $greg_correction = 0;
1034    } else
1035      $greg_correction = 0;
1036    if($month > 2)
1037        $month -= 2;
1038    else {
1039        $month += 10;
1040        $year--;
1041    }
1042    $day = (floor((13 * $month - 1) / 5) +
1043      $day + ($year % 100) +
1044      floor(($year % 100) / 4) +
1045      floor(($year / 100) / 4) - 2 *
1046      floor($year / 100) + 77 + $greg_correction);
1047    $weekday_number = $day - 7 * floor($day / 7);
1048    return $weekday_number;
1049  }
1050  
1051  /**
1052   * Returns true for a leap year, else false. Works outside normal date range.
1053   *
1054   * @param int  $year
1055   * @return boolean
1056   */
1057  function date_is_leap_year($year) {
1058    if ($year < 1000) {
1059      return false;
1060    }
1061    if ($year < 1582) { // pre Gregorio XIII - 1582
1062      return ($year % 4 == 0);
1063    }
1064    else {  // post Gregorio XIII - 1582
1065      return (($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400 == 0);
1066    }
1067  }
1068  
1069  /**
1070   * @} End of ingroup "datelib".
1071   */


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