/** * Returns the approximate difference in time, discarding any unit of measure but the least specific. * * The output will read like: * * - "This time is `{return value}` the provided one" when a time it passed * - "This time is `{return value}`" when no time is passed and comparing with the current time * * Examples of output for a time passed might be: * * - `'5 minutes after'` * - `'2 hours before'` * - `'at the same time'` * * Examples of output for no time passed might be: * * - `'5 minutes ago'` * - `'2 hours ago'` * - `'right now'` * * You would never get the following output since it includes more than one unit of time measurement: * * - `'5 minutes and 28 seconds'` * - `'1 hour, 15 minutes'` * * Values that are close to the next largest unit of measure will be rounded up: * * - `'55 minutes'` would be represented as `'1 hour'`, however `'45 minutes'` would not * * @param fTime|object|string|integer $other_time The time to create the difference with, `NULL` is interpreted as now * @param boolean $simple When `TRUE`, the returned value will only include the difference in the two times, but not `from now`, `ago`, `after` or `before` * @param boolean :$simple * @return string The fuzzy difference in time between the this time and the one provided */ public function getFuzzyDifference($other_time = NULL, $simple = FALSE) { if (is_bool($other_time)) { $simple = $other_time; $other_time = NULL; } $relative_to_now = FALSE; if ($other_time === NULL) { $relative_to_now = TRUE; } $other_time = new fTime($other_time); $diff = $this->time - $other_time->time; if (abs($diff) < 10) { if ($relative_to_now) { return self::compose('right now'); } return self::compose('at the same time'); } static $break_points = array(); if (!$break_points) { $break_points = array(45 => array(1, self::compose('second'), self::compose('seconds')), 2700 => array(60, self::compose('minute'), self::compose('minutes')), 64800 => array(3600, self::compose('hour'), self::compose('hours')), 432000 => array(86400, self::compose('day'), self::compose('days'))); } foreach ($break_points as $break_point => $unit_info) { if (abs($diff) > $break_point) { continue; } $unit_diff = round(abs($diff) / $unit_info[0]); $units = fGrammar::inflectOnQuantity($unit_diff, $unit_info[1], $unit_info[2]); break; } if ($simple) { return self::compose('%1$s %2$s', $unit_diff, $units); } if ($relative_to_now) { if ($diff > 0) { return self::compose('%1$s %2$s from now', $unit_diff, $units); } return self::compose('%1$s %2$s ago', $unit_diff, $units); } if ($diff > 0) { return self::compose('%1$s %2$s after', $unit_diff, $units); } return self::compose('%1$s %2$s before', $unit_diff, $units); }
/** * Returns the approximate difference in time, discarding any unit of measure but the least specific. * * The output will read like: * * - "This timestamp is `{return value}` the provided one" when a timestamp it passed * - "This timestamp is `{return value}`" when no timestamp is passed and comparing with the current timestamp * * Examples of output for a timestamp passed might be: * * - `'5 minutes after'` * - `'2 hours before'` * - `'2 days after'` * - `'at the same time'` * * Examples of output for no timestamp passed might be: * * - `'5 minutes ago'` * - `'2 hours ago'` * - `'2 days from now'` * - `'1 year ago'` * - `'right now'` * * You would never get the following output since it includes more than one unit of time measurement: * * - `'5 minutes and 28 seconds'` * - `'3 weeks, 1 day and 4 hours'` * * Values that are close to the next largest unit of measure will be rounded up: * * - `'55 minutes'` would be represented as `'1 hour'`, however `'45 minutes'` would not * - `'29 days'` would be represented as `'1 month'`, but `'21 days'` would be shown as `'3 weeks'` * * @param fTimestamp|object|string|integer $other_timestamp The timestamp to create the difference with, `NULL` is interpreted as now * @return string The fuzzy difference in time between the this timestamp and the one provided */ public function getFuzzyDifference($other_timestamp = NULL) { $relative_to_now = FALSE; if ($other_timestamp === NULL) { $relative_to_now = TRUE; } $other_timestamp = new fTimestamp($other_timestamp); $diff = $this->timestamp - $other_timestamp->timestamp; if (abs($diff) < 10) { if ($relative_to_now) { return self::compose('right now'); } return self::compose('at the same time'); } $break_points = array(45 => array(1, self::compose('second'), self::compose('seconds')), 2700 => array(60, self::compose('minute'), self::compose('minutes')), 64800 => array(3600, self::compose('hour'), self::compose('hours')), 432000 => array(86400, self::compose('day'), self::compose('days')), 1814400 => array(604800, self::compose('week'), self::compose('weeks')), 23328000 => array(2592000, self::compose('month'), self::compose('months')), 2147483647 => array(31536000, self::compose('year'), self::compose('years'))); foreach ($break_points as $break_point => $unit_info) { if (abs($diff) > $break_point) { continue; } $unit_diff = round(abs($diff) / $unit_info[0]); $units = fGrammar::inflectOnQuantity($unit_diff, $unit_info[1], $unit_info[2]); break; } if ($relative_to_now) { if ($diff > 0) { return self::compose('%1$s %2$s from now', $unit_diff, $units); } return self::compose('%1$s %2$s ago', $unit_diff, $units); } if ($diff > 0) { return self::compose('%1$s %2$s after', $unit_diff, $units); } return self::compose('%1$s %2$s before', $unit_diff, $units); }
/** * Prints out a piece of a template * * @param string $template The name of the template to print * @param string $piece The piece of the template to print * @param array $data The data to replace the variables with * @return void */ private static function printPiece($template, $name, $data) { if (!isset(self::$templates[$template]['pieces'][$name])) { throw new fProgrammerException('The template piece, %s, was not specified when defining the %s template', $name, $template); } $piece = self::$templates[$template]['pieces'][$name]; preg_match_all('#\\{\\{ (\\w+)((?:\\|\\w+)+)? \\}\\}#', $piece, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $variable = $match[1]; $value = !isset($data[$variable]) ? NULL : $data[$variable]; if (isset($match[2])) { $filters = array_slice(explode('|', $match[2]), 1); foreach ($filters as $filter) { if (!in_array($filter, self::$filters)) { throw new fProgrammerException('The filter specified, %1$s, is invalid. Must be one of: %2$s.', $filter, join(', ', self::$filters)); } if (!strlen($value)) { continue; } if ($filter == 'inflect') { $value = fGrammar::inflectOnQuantity($data['total_records'], $value); } elseif ($filter == 'lower') { $value = fUTF8::lower($value); } elseif ($filter == 'url_encode') { $value = urlencode($value); } elseif ($filter == 'humanize') { $value = fGrammar::humanize($value); } } } $piece = preg_replace('#' . preg_quote($match[0], '#') . '#', fHTML::encode($value), $piece, 1); } echo $piece; }
/** * Returns the approximate difference in time, discarding any unit of measure but the least specific. * * The output will read like: * * - "This date is `{return value}` the provided one" when a date it passed * - "This date is `{return value}`" when no date is passed and comparing with today * * Examples of output for a date passed might be: * * - `'2 days after'` * - `'1 year before'` * - `'same day'` * * Examples of output for no date passed might be: * * - `'2 days from now'` * - `'1 year ago'` * - `'today'` * * You would never get the following output since it includes more than one unit of time measurement: * * - `'3 weeks and 1 day'` * - `'1 year and 2 months'` * * Values that are close to the next largest unit of measure will be rounded up: * * - `6 days` would be represented as `1 week`, however `5 days` would not * - `29 days` would be represented as `1 month`, but `21 days` would be shown as `3 weeks` * * @param fDate|object|string|integer $other_date The date to create the difference with, `NULL` is interpreted as today * @param boolean $simple When `TRUE`, the returned value will only include the difference in the two dates, but not `from now`, `ago`, `after` or `before` * @param boolean :$simple * @return string The fuzzy difference in time between the this date and the one provided */ public function getFuzzyDifference($other_date = NULL, $simple = FALSE) { if (is_bool($other_date)) { $simple = $other_date; $other_date = NULL; } $relative_to_now = FALSE; if ($other_date === NULL) { $relative_to_now = TRUE; } $other_date = new fDate($other_date); $diff = $this->date - $other_date->date; if (abs($diff) < 86400) { if ($relative_to_now) { return self::compose('today'); } return self::compose('same day'); } static $break_points = array(); if (!$break_points) { $break_points = array(432000 => array(86400, self::compose('day'), self::compose('days')), 1814400 => array(604800, self::compose('week'), self::compose('weeks')), 23328000 => array(2592000, self::compose('month'), self::compose('months')), 2147483647 => array(31536000, self::compose('year'), self::compose('years'))); } foreach ($break_points as $break_point => $unit_info) { if (abs($diff) > $break_point) { continue; } $unit_diff = round(abs($diff) / $unit_info[0]); $units = fGrammar::inflectOnQuantity($unit_diff, $unit_info[1], $unit_info[2]); break; } if ($simple) { return self::compose('%1$s %2$s', $unit_diff, $units); } if ($relative_to_now) { if ($diff > 0) { return self::compose('%1$s %2$s from now', $unit_diff, $units); } return self::compose('%1$s %2$s ago', $unit_diff, $units); } if ($diff > 0) { return self::compose('%1$s %2$s after', $unit_diff, $units); } return self::compose('%1$s %2$s before', $unit_diff, $units); }