From f2e50664301f5f7df2574ab50e5e676d4e3e0bb6 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Fri, 10 Apr 2015 09:44:38 +0200 Subject: [PATCH] lib: Add DateFormatter for ICU date formatting The DateFormatter class is supposed to handle locale-dependent date, time, and time diff (ago, since, until) formatting. refs #6778 --- library/Icinga/Date/DateFormatter.php | 226 ++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 library/Icinga/Date/DateFormatter.php diff --git a/library/Icinga/Date/DateFormatter.php b/library/Icinga/Date/DateFormatter.php new file mode 100644 index 000000000..79523d0a4 --- /dev/null +++ b/library/Icinga/Date/DateFormatter.php @@ -0,0 +1,226 @@ +format = $format; + } + + /** + * Create a date formatter + * + * @param int $format + * + * @return static + */ + public static function create($format) + { + return new static($format); + } + + /** + * Format the diff between two date/time values as a string + * + * @param int|float $time + * @param int|float $now + * + * @return string The formatted string + */ + protected function diff($time, $now = null) + { + $now = $now === null ? time() : (float) $now; + $invert = false; + $diff = $time - $now; + if ($diff < 0) { + $diff = abs($diff); + $invert = true; + } + if ($diff > 3600 * 24 * 3) { + $type = static::DATETIME; + $fmt = new IntlDateFormatter(null, IntlDateFormatter::SHORT, IntlDateFormatter::SHORT); + $formatted = $fmt->format($time); + } else { + $minutes = floor($diff / 60); + if ($minutes < 60) { + $type = static::$relative; + $formatted = sprintf('%dm %ds', $minutes, $diff % 60); + } else { + $hours = floor($minutes / 60); + if ($hours < 24) { + $type = static::TIME; + $fmt = new IntlDateFormatter(null, IntlDateFormatter::NONE, IntlDateFormatter::SHORT); + $formatted = $fmt->format($time); + } else { + $type = static::$relative; + $formatted = sprintf('%dd %dh', floor($hours / 24), $hours % 24); + } + } + } + switch ($this->format) { + case static::AGO: + switch ($type) { + case static::$relative: + $formatted = sprintf( + t('%s ago', 'An event that happened the given time interval ago'), + $formatted + ); + break; + case static::TIME: + $formatted = sprintf(t('at %s', 'An event that happened at the given time'), $formatted); + break; + case static::DATETIME: + $formatted = sprintf( + t('on %s', 'An event that happened at the given date and time'), + $formatted + ); + break; + } + break; + case static::UNTIL: + switch ($type) { + case static::$relative: + $formatted = sprintf( + t('in %s', 'An event will happen after the given time interval has elapsed'), + $invert ? ('-' . $formatted) : $formatted + ); + break; + case static::TIME: + $formatted = sprintf(t('at %s', 'An event will happen at the given time'), $formatted); + break; + case static::DATETIME: + $formatted = sprintf(t('on %s', 'An event will happen on the given date and time'), $formatted); + break; + } + break; + case static::SINCE; + switch ($type) { + case static::$relative: + $formatted = sprintf( + t('for %s', 'A status is lasting for the given time interval'), + $formatted + ); + break; + case static::TIME: + // Move to next case + case static::DATETIME: + $formatted = sprintf( + t('since %s', 'A status is lasting since the given date and time'), + $formatted + ); + break; + } + break; + default: + break; + } + return $formatted; + } + + /** + * Format a date/time value as a string + * + * @param int|float $time Date/time to format + * @param int|float $now + * + * @return string The formatted string + */ + public function format($time, $now = null) + { + $time = (float) $time; + switch ($this->format) { + case static::TIME: + $fmt = new IntlDateFormatter(null, IntlDateFormatter::NONE, IntlDateFormatter::SHORT); + $formatted = $fmt->format($time); + break; + case static::DATE; + $fmt = new IntlDateFormatter(null, IntlDateFormatter::SHORT, IntlDateFormatter::NONE); + $formatted = $fmt->format($time); + break; + case static::DATETIME; + $fmt = new IntlDateFormatter(null, IntlDateFormatter::SHORT, IntlDateFormatter::SHORT); + $formatted = $fmt->format($time); + break; + case static::AGO: + // Move to next case + case static::UNTIL: + // Move to next case + case static::SINCE: + $formatted = $this->diff($time, $now); + break; + default: + throw new InvalidArgumentException('Invalid format'); + } + return $formatted; + } +}