<?php /* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */ namespace Icinga\Date; use IntlDateFormatter; use InvalidArgumentException; /** * ICU date formatting */ class DateFormatter { /** * Internal constant for relative time diffs * * @var int */ protected static $relative = 0; /** * Format time * * @var int */ const TIME = 1; /** * Format date * * @var int */ const DATE = 2; /** * Format date and time * * @var int */ const DATETIME = 4; /** * Format time diff as time ago * * @var int */ const AGO = 8; /** * Format time diff as time until * * @var int */ const UNTIL = 16; /** * Format time diff as time since * * @var int */ const SINCE = 32; /** * Format used for the DateFormatter * * @var int */ protected $format; /** * Create a date formatter * * @param int $format */ public function __construct($format) { $this->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; } }