You are here

function partial_date_mktime in Partial Date 7

Creates a timestamp based on the available components.

Copied from Zend_Date. Significantly modified.

Parameters

array $components: An array of all the defined date components including timezone.

Return value

integer|float An approx. timestamp (number of seconds elapsed relative to 1970/01/01 00:00:00 GMT/UTC)

File

./partial_date.module, line 1349
Defines a date element that allows for any combination of date granularity settings.

Code

function partial_date_mktime(array $components) {
  $components = array_intersect_key($components, partial_date_components());
  extract($components, EXTR_SKIP);
  if (1901 < $year and $year < 2038) {
    $oldzone = @date_default_timezone_get();
    if ($timezone && $timezone != $oldzone) {
      date_default_timezone_set($timezone);
    }
    $result = @mktime($hour, $minute, $second, $month, $day, $year);
    if ($timezone && $timezone != $oldzone) {
      date_default_timezone_set($oldzone);
    }
    if ($result !== FALSE) {
      return $result;
    }
  }

  // Get approx. offset

  # Error in float pre 1900 probably makes this pointless

  #        if ($gmt !== true) {

  #          $tz = new DateTimeZone($timezone);

  #          $second += $tz->getOffset(date_create('2000-01-01 00:00 GMT'));

  #        }

  // date to integer
  $day = intval($day);
  $month = intval($month);
  $year = intval($year);
  $_monthTable = partial_date_month_matrix();
  if ($month > 12) {
    $overlap = floor($month / 12);
    $year += $overlap;
    $month -= $overlap * 12;
  }
  else {
    $overlap = ceil((1 - $month) / 12);
    $year -= $overlap;
    $month += $overlap * 12;
  }
  $date = 0;

  // correct months > 12 and months < 1
  if ($year < -99999 || $year > 99999) {

    // Calculate the average number of seconds in a year.
    $seconds_in_year = ($year - 1970) * PD2_SEC_PER_YEAR;
    $leapyear = partial_date_is_leap_year($year);
    for ($mcount = 0; $mcount < $month - 1; $mcount++) {
      $date += $_monthTable[$mcount];
      if ($leapyear === true and $mcount == 1) {
        $date++;
      }
    }
    $date += $day - 1;
    $date = $date * 86400 + $hour * 3600 + $minute * 60 + $second + $seconds_in_year;
  }
  elseif ($year >= 1970) {

    // Date is after UNIX epoch
    // go through leapyears
    // add months from latest given year
    for ($count = 1970; $count <= $year; $count++) {
      $leapyear = partial_date_is_leap_year($count);
      if ($count < $year) {
        $date += 365;
        if ($leapyear === true) {
          $date++;
        }
      }
      else {
        for ($mcount = 0; $mcount < $month - 1; $mcount++) {
          $date += $_monthTable[$mcount];
          if ($leapyear === true and $mcount == 1) {
            $date++;
          }
        }
      }
    }
    $date += $day - 1;
    $date = $date * 86400 + $hour * 3600 + $minute * 60 + $second;
  }
  else {

    // Date is before UNIX epoch
    // go through leapyears
    // add months from latest given year
    for ($count = 1969; $count >= $year; $count--) {
      $leapyear = partial_date_is_leap_year($count);
      if ($count > $year) {
        $date += 365;
        if ($leapyear === true) {
          $date++;
        }
      }
      else {
        for ($mcount = 11; $mcount > $month - 1; $mcount--) {
          $date += $_monthTable[$mcount];
          if ($leapyear === true and $mcount == 2) {
            $date++;
          }
        }
      }
    }
    $date += $_monthTable[$month - 1] - $day;
    $date = -($date * 86400 + (86400 - ($hour * 3600 + $minute * 60 + $second)));

    // gregorian correction for 5.Oct.1582
    if ($date < -12220185600) {
      $date += 864000;
    }
    elseif ($date < -12219321600) {
      $date = -12219321600;
    }
  }
  return $date;
}