Промежуток времени по-русски
12 ноября 2011 г.
Функция отдает человеческое представление о промежутке времени, заданном в секундах.
function ru_period($format,$seconds=false,$form=false)
{
if(!function_exists('num_word')) { function num_word($n,$a,$b,$c,$m=1){$n=sprintf("%.0f",$n);$x=abs($n>9?mb_substr($n,-2):$n);return($m?($m==2?number_format($n,0,' ',' '):$n).' ':'').(($x%=100)>9&&$x<20||($x%=10)>4||$x==0?$c:($x==1?$a:$b));} }
if(is_numeric($format) && is_bool($seconds) && $form===false) { $form = $seconds; $seconds = $format; $format = 'yMdhms'; }
else foreach(array('с'=>'s','м'=>'m','ч'=>'h','д'=>'d','н'=>'w','М'=>'M','г'=>'y',) as $from=>$to) $format = str_replace($from,$to,$format);
$seconds = abs($seconds);
$words = array('s'=>array(($form?'секунду':'секунда'),'секунды','секунд'),'m'=>array(($form?'минуту':'минута'),'минуты','минут'),'h'=>array('час','часа','часов'),'d'=>array('день','дня','дней'),'w'=>array(($form?'неделю':'неделя'),'недели','недель'),'M'=>array('месяц','месяца','месяцев'),'y'=>array('год','года','лет'));
$times = array('y'=>86400*30.4375*12,'M'=>86400*30.4375,'w'=>86400*7,'d'=>86400,'h'=>3600,'m'=>60,'s'=>1);
$counts = array();
$left = $seconds;
for($i=0;$i$count) { $res .= num_word($count,$words[$unit][0],$words[$unit][1],$words[$unit][2]).($i==count($counts)-1?'':($i==count($counts)-2?' и ':', ')); $i++; }
return $res;
}
В качестве результата может выводиться количество лет, месяцев, недель, дней, часов, минут и секунд. За это отвечают значения параметра
$format
в виде русских или латинских букв:
y или г |
Годы |
M или М |
Месяцы |
w или н |
Недели |
d или д |
Дни (сутки) |
h или ч |
Часы |
m или м |
Минуты |
s или с |
Секунды |
Параметры можно сочетать в порядке убывания временных единиц (годы, месяцы, недели, дни, часы, минуты, секунды). На выходе все правила лексики и пунктуации русского языка будут соблюдаться. Нулевые значения пропускаются. Формат можно вообще не указывать, по умолчанию он будет
yMdhms
(т. е. функция покажет все, кроме количества недель). Третий параметр,
$form
, дополнительно отвечает за изменение словоформ.
Примеры использования:
echo ru_period('дчм',100000); // выведет "1 день, 3 часа и 46 минут"
echo ru_period('ндчм',100000); // выведет то же самое, т. к. 100000 секунд меньше недели, а нулевые значения исключаются из результата
echo ru_period('мчд',100000); // "1666 минут" (как если бы вместо "мчд" было просто "м"), т. к. буквы формата идут в неправильном порядке
echo ru_period('чмд',100000); // "27 часов и 46 минут" (количество дней пропустится по причине ошибки из предыдущего примера)
echo ru_period('г',100000); // отдаст пустую строку (100000 секунд меньше года)
echo ru_period(100000000); // "3 года, 2 месяца, 18 часов, 46 минут и 40 секунд"
echo ru_period('нд',100000000); // "165 недель и 2 дня"
echo ru_period('чмс',3661); // "1 час, 1 минута и 1 секунда"
echo ru_period('чмс',3661,true); // "1 час, 1 минуту и 1 секунду"
С учетом високосности количество дней в году усреднено до 365,25. В месяце, соответственно, их 30,4375. На этой почве возможно пренебрежимо малое расхождение результата с реальностью.