|
|
@@ -0,0 +1,108 @@ |
|
|
<?php |
|
|
/** |
|
|
* Русскоязычный DateTime с дополнениями |
|
|
* |
|
|
* @author Aleksandr <aleksandr@aleksandr.ru> |
|
|
* @link http://www.aleksandr.ru author's website |
|
|
*/ |
|
|
class DateTimeRu extends DateTime |
|
|
{ |
|
|
protected static $FN = array(1=>"Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"); |
|
|
protected static $F = array(1=>"Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря"); |
|
|
protected static $M = array(1=>"Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"); |
|
|
protected static $l = array("Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"); |
|
|
protected static $D = array("Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"); |
|
|
|
|
|
protected static $timeStrFormat = array( |
|
|
// будущее |
|
|
0 => array( |
|
|
'y' => array('Более чем через год', 'Более чем через год', 'Более чем через год'), |
|
|
'm' => array('Через месяц', 'Через %m месяца', 'Через %m месяцев'), |
|
|
'd' => array('Завтра', 'Через %d дня', 'Через %d дней'), |
|
|
'h' => array('Через час', 'Через %h часа', 'Через %h часов'), |
|
|
'i' => array('Через минуту', 'Через %i минуты', 'Через %i минут'), |
|
|
's' => array('Через секунду', 'Через %s секунды', 'Через %s секунд'), |
|
|
), |
|
|
// прошлое |
|
|
1 => array( |
|
|
'y' => array('Более года назад', 'Более года назад', 'Более года назад'), |
|
|
'm' => array('Месяц назад', '%m месяца назад', '%m месяцев назад'), |
|
|
'd' => array('Вчера', '%d дня назад', '%d дней назад'), |
|
|
'h' => array('Час назад', '%h часа назад', '%h часов назад'), |
|
|
'i' => array('Минуту назад', '%h минуты назад', '%h минут назад'), |
|
|
's' => array('Секунду назад', '%s секунды назад', '%s секунд назад'), |
|
|
), |
|
|
// сейчас |
|
|
'now' => 'Сейчас' |
|
|
); |
|
|
|
|
|
/** |
|
|
* Форматировать дату/время |
|
|
* @param string $format |
|
|
* @param bool $nominativeMonth месяц в именительном падеже |
|
|
* @return string |
|
|
*/ |
|
|
function format($format, $nominativeMonth = FALSE) |
|
|
{ |
|
|
$t = $this->getTimestamp(); |
|
|
$n = date('n', $t); // Порядковый номер месяца без ведущего нуля от 1 до 12 |
|
|
$w = date('w', $t); // Порядковый номер дня недели от 0 (воскресенье) до 6 (суббота) |
|
|
$format = str_replace('F', $nominativeMonth ? static::$FN[$n] : static::$F[$n], $format); |
|
|
$format = str_replace('M', static::$M[$n], $format); |
|
|
$format = str_replace('l', static::$l[$w], $format); |
|
|
$format = str_replace('D', static::$D[$w], $format); |
|
|
return parent::format($format); |
|
|
} |
|
|
|
|
|
/** |
|
|
* Получить красивую строку раницы во времени от текущего |
|
|
* @param int $skipSeconds количество секунд, менее которого приравнивается к 'сейчас' |
|
|
* @return string например '15 минут назад' |
|
|
*/ |
|
|
function getTimeDiffStr($skipSeconds = 60) |
|
|
{ |
|
|
$dt = new DateTime(); |
|
|
$diff = $dt->diff($this); |
|
|
// $diff->invert |
|
|
// Принимает 1, если интервал представляет отрицательный период времени и 0 в противном случае. |
|
|
|
|
|
if(static::DateIntervalToSeconds($diff) > $skipSeconds) { |
|
|
if($diff->y) return $diff->format(static::morphEnding($diff->y, static::$timeStrFormat[$diff->invert]['y'])); |
|
|
if($diff->m) return $diff->format(static::morphEnding($diff->m, static::$timeStrFormat[$diff->invert]['m'])); |
|
|
if($diff->d) return $diff->format(static::morphEnding($diff->d, static::$timeStrFormat[$diff->invert]['d'])); |
|
|
if($diff->h) return $diff->format(static::morphEnding($diff->h, static::$timeStrFormat[$diff->invert]['h'])); |
|
|
if($diff->i) return $diff->format(static::morphEnding($diff->i, static::$timeStrFormat[$diff->invert]['i'])); |
|
|
if($diff->s) return $diff->format(static::morphEnding($diff->s, static::$timeStrFormat[$diff->invert]['s'])); |
|
|
} |
|
|
return $diff->format(static::$timeStrFormat['now']); |
|
|
} |
|
|
|
|
|
/** |
|
|
* морфологическое окончание |
|
|
* @param int $n количество |
|
|
* @param array $titles = ['1 яблоко', '2 яблока', '5 яблок'] |
|
|
* @return string |
|
|
*/ |
|
|
static function morphEnding($n, $titles) |
|
|
{ |
|
|
$cases = array(2, 0, 1, 1, 1, 2); |
|
|
return $titles[($n % 100 > 4 && $n % 100 < 20) ? 2 : $cases[min($n % 10, 5)]]; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Keep in mind that a year is seen in this class as 365 days, and a month is seen as 30 days. |
|
|
* It is not possible to calculate how many days are in a given year or month without a point of reference in time. |
|
|
* @see http://php.net/manual/ru/dateinterval.format.php#102271 |
|
|
* @param DateInterval $di |
|
|
* @return int |
|
|
*/ |
|
|
static function DateIntervalToSeconds($di) |
|
|
{ |
|
|
return ($di->y * 365 * 24 * 60 * 60) + |
|
|
($di->m * 30 * 24 * 60 * 60) + |
|
|
($di->d * 24 * 60 * 60) + |
|
|
($di->h * 60 * 60) + |
|
|
($di->i * 60) + |
|
|
($di->s); |
|
|
} |
|
|
} |