| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- <?php
- /**
- * @file
- * Date handling functions.
- */
- /**
- * Helper function to convert dates from Unix timestamps into ISO 8601 format.
- *
- * @param $timestamp
- * An integer containing the Unix timestamp being converted.
- * @param $gap
- * A string containing the gap, see FACETAPI_DATE_* constants for valid
- * values. Defaults to FACETAPI_DATE_SECOND.
- *
- * @return
- * A string containing the date in ISO 8601 format.
- */
- function facetapi_isodate($timestamp, $gap = FACETAPI_DATE_SECOND) {
- switch ($gap) {
- case FACETAPI_DATE_SECOND:
- $format = FACETAPI_DATE_ISO8601;
- break;
- case FACETAPI_DATE_MINUTE:
- $format = 'Y-m-d\TH:i:00\Z';
- break;
- case FACETAPI_DATE_HOUR:
- $format = 'Y-m-d\TH:00:00\Z';
- break;
- case FACETAPI_DATE_DAY:
- $format = 'Y-m-d\T00:00:00\Z';
- break;
- case FACETAPI_DATE_MONTH:
- $format = 'Y-m-01\T00:00:00\Z';
- break;
- case FACETAPI_DATE_YEAR:
- $format = 'Y-01-01\T00:00:00\Z';
- break;
- default:
- $format = FACETAPI_DATE_ISO8601;
- break;
- }
- return gmdate($format, $timestamp);
- }
- /**
- * Return a date gap one increment smaller than the one passed.
- *
- * @param $gap
- * A string containing the gap, see FACETAPI_DATE_* constants for valid
- * values.
- * @param $min_gap
- * A string containing the the minimum gap that can be returned, defaults to
- * FACETAPI_DATE_SECOND. This is useful for defining the smallest increment
- * that can be used in a date drilldown.
- *
- * @return
- * A string containing the smaller date gap, NULL if there is no smaller gap.
- * See FACETAPI_DATE_* constants for valid values.
- */
- function facetapi_get_next_date_gap($gap, $min_gap = FACETAPI_DATE_SECOND) {
- // Array of numbers used to determine whether the next gap is smaller than
- // the minimum gap allowed in the drilldown.
- $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,
- );
- // 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 incremenet.
- 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;
- }
- }
|