6, FACETAPI_DATE_MONTH => 5, FACETAPI_DATE_DAY => 4, FACETAPI_DATE_HOUR => 3, FACETAPI_DATE_MINUTE => 2, FACETAPI_DATE_SECOND => 1, ); // Gets gap numbers for both the gap and minimum gap, checks if the next gap // is within the limit set by the $min_gap parameter. $gap_num = isset($gap_numbers[$gap]) ? $gap_numbers[$gap] : 6; $min_num = isset($gap_numbers[$min_gap]) ? $gap_numbers[$min_gap] : 1; return ($gap_num > $min_num) ? array_search($gap_num - 1, $gap_numbers) : $min_gap; } /** * Determines the best search gap to use for an arbitrary date range. * * Generally, we use the maximum gap that fits between the start and end date. * If they are more than a year apart, 1 year; if they are more than a month * apart, 1 month; etc. * * This function uses Unix timestamps for its computation and so is not useful * for dates outside that range. * * @param int $start_time * A string containing the start date as an ISO date string. * @param int $end_time * A string containing the end date as an ISO date string. * @param string|NULL $min_gap * (Optional) The minimum gap that should be returned. * * @return string * A string containing the gap, see FACETAPI_DATE_* constants for valid * values. Returns FALSE of either of the dates cannot be converted to a * timestamp. */ function facetapi_get_timestamp_gap($start_time, $end_time, $min_gap = NULL) { $time_diff = $end_time - $start_time; switch (TRUE) { // NOTE: 31536000 == 60 * 60 * 24 * 365 case ($time_diff >= 31536000): $gap = FACETAPI_DATE_YEAR; break; case ($time_diff >= 86400 * gmdate('t', $start_time)): $gap = FACETAPI_DATE_MONTH; break; case ($time_diff >= 86400): $gap = FACETAPI_DATE_DAY; break; case ($time_diff >= 3600): $gap = FACETAPI_DATE_HOUR; break; case ($time_diff >= 60): $gap = FACETAPI_DATE_MINUTE; break; default: $gap = FACETAPI_DATE_SECOND; break; } // Return the calculated gap if a minimum gap was not passed of the calculated // gap is a larger interval than the minimum gap. if (null === $min_gap || facetapi_gap_compare($gap, $min_gap) >= 0) { return $gap; } else { return $min_gap; } } /** * Converts ISO date strings to Unix timestamps, passes values to the * facetapi_get_timestamp_gap() function to calculate the gap. * * @param $start_date * A string containing the start date as an ISO date string. * @param $end_date * A string containing the end date as an ISO date string. * @param string|NULL $min_gap * (Optional) The minimum gap that should be returned. * * @return string * A string containing the gap, see FACETAPI_DATE_* constants for valid * values. Returns FALSE of either of the dates cannot be converted to a * timestamp. * * @see facetapi_get_timestamp_gap() */ function facetapi_get_date_gap($start_date, $end_date, $min_gap = NULL) { $range = array(strtotime($start_date), strtotime($end_date)); if (!in_array(FALSE, $range, TRUE)) { return facetapi_get_timestamp_gap($range[0], $range[1], $min_gap); } return FALSE; } /** * Returns a formatted date based on the passed timestamp and gap. * * This function assumes that gaps less than one day will be displayed in a * search context in which a larger containing gap including a day is already * displayed. So, HOUR, MINUTE, and SECOND gaps only display time information, * without date. * * @param $timestamp * An integer containing the Unix timestamp. * @param $gap * A string containing the gap, see FACETAPI_DATE_* constants for valid * values, defaults to YEAR. * * @return * A gap-appropriate display date used in the facet link. */ function facetapi_format_timestamp($timestamp, $gap = FACETAPI_DATE_YEAR) { switch ($gap) { case FACETAPI_DATE_MONTH: return format_date($timestamp, 'custom', 'F Y', 'UTC'); case FACETAPI_DATE_DAY: return format_date($timestamp, 'custom', 'F j, Y', 'UTC'); case FACETAPI_DATE_HOUR: return format_date($timestamp, 'custom', 'g A', 'UTC'); case FACETAPI_DATE_MINUTE: return format_date($timestamp, 'custom', 'g:i A', 'UTC'); case FACETAPI_DATE_SECOND: return format_date($timestamp, 'custom', 'g:i:s A', 'UTC'); default: return format_date($timestamp, 'custom', 'Y', 'UTC'); } } /** * Returns a formatted date based on the passed ISO date string and gap. * * @param $date * A string containing the date as an ISO date string. * @param $gap * A string containing the gap, see FACETAPI_DATE_* constants for valid * values, defaults to YEAR. * @param $callback * The formatting callback, defaults to "facetapi_format_timestamp". * * @return * A gap-appropriate display date used in the facet link. * * @see facetapi_format_timestamp() */ function facetapi_format_date($date, $gap = FACETAPI_DATE_YEAR, $callback = 'facetapi_format_timestamp') { $timestamp = strtotime($date); return $callback($timestamp, $gap); } /** * Returns the next increment from the given ISO date and gap. This function is * useful for getting the upper limit of a date range from the given start * date. * * @param $date * A string containing the date as an ISO date string. * @param $gap * A string containing the gap, see FACETAPI_DATE_* constants for valid * values, defaults to YEAR. * * @return * A string containing the date, FALSE if the passed date could not be parsed. */ function facetapi_get_next_date_increment($date, $gap) { if (preg_match(FACETAPI_REGEX_DATE, $date, $match)) { // Increments the timestamp. switch ($gap) { case FACETAPI_DATE_MONTH: $match[2] += 1; break; case FACETAPI_DATE_DAY: $match[3] += 1; break; case FACETAPI_DATE_HOUR: $match[4] += 1; break; case FACETAPI_DATE_MINUTE: $match[5] += 1; break; case FACETAPI_DATE_SECOND: $match[6] += 1; break; default: $match[1] += 1; break; } // Gets the next increment. return facetapi_isodate( gmmktime($match[4], $match[5], $match[6], $match[2], $match[3], $match[1]) ); } return FALSE; } /** * Compares two timestamp gaps. * * @param string $gap1 * @param string $gap2 * * @return int * Returns -1 if gap1 is less than gap2, 1 if gap1 is greater than gap2, and 0 * if they are equal. */ function facetapi_gap_compare($gap1, $gap2) { $gap_numbers = array( FACETAPI_DATE_YEAR => 6, FACETAPI_DATE_MONTH => 5, FACETAPI_DATE_DAY => 4, FACETAPI_DATE_HOUR => 3, FACETAPI_DATE_MINUTE => 2, FACETAPI_DATE_SECOND => 1, ); $gap1_num = isset($gap_numbers[$gap1]) ? $gap_numbers[$gap1] : 6; $gap2_num = isset($gap_numbers[$gap2]) ? $gap_numbers[$gap2] : 6; if ($gap1_num == $gap2_num) { return 0; } else { return ($gap1_num < $gap2_num) ? -1 : 1; } }