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
This commit is contained in:
parent
06830e035e
commit
f2e5066430
|
@ -0,0 +1,226 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue