Данила Лучинский6.0
Дизайнер, верстальщик, программист
+7 921 308-88-38 ICQ 344-00-443 Сообщение  
dan@luchinsky.ru danluchinsky Заказать сайт
Кодоводство

Промежуток времени по-русски

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<mb_strlen($format);$i++) { if(!array_key_exists($format[$i],$words)) continue; if(!$floor = floor($left/$times[$format[$i]])) continue; $counts[$format[$i]] = $floor; $left = $left % $times[$format[$i]]; } $res = ''; $i = 0; foreach($counts as $unit=>$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. На этой почве возможно пренебрежимо малое расхождение результата с реальностью.
Метки:  PHP