Числа прописью с рублями, минутами и метрами

Краткое описание алгоритмов date-diff, очень просто!

Propis::get("919.12") => девятьсот девятнадцать рублей 12 копеек;

Propis::get("1071.11") => одна тысяча семьдесят один рубль 11 копеек;

Propis::get("9.11.2") => девять часов одиннадцать минут две секунды;

Propis::get("1002000219.02") => один миллиард два миллиона двести девятнадцать рублей 02 копейки;

Propis::get("23:14:09") => двадцать три часа четырнадцать минут девять секунд;

Propis::get("2-3-00 12:00:54") => два года три месяца 0 дней двенадцать часов 0 минут пятьдесят четыре секунды;

Propis::get_one(2354547758301125, array("миллиметр", "миллиметра", "миллиметров")) => 2 354 пятьсот сорок семь миллиардов семьсот пятьдесят восемь миллионов триста одна тысяча сто двадцать пять миллиметров;

Propis::get(n_time_diff ("2013-01-01 00:00:00")) => В Иркутске до Нового Года осталось: 0 часов 0 минут 0 секунд;

Исходный код:

<?php
//////////////////////////
include 'header1.php'//это для строк с примерами. 
//При использовании скрипта в другом месте убрать!!

class Propis 
{
    private static 
$def = array (
        
'forms' => array(2011122222),
        
        
'words' => array(
            
=> array('секунда''секунды''секунд'),
            
=> array('минута''минуты''минут'),
            
=> array('час''часа''часов'),
            
=> array('день''дня''дней'),
            
=> array('месяц''месяца''месяцев'),
            
=> array('год''года''лет'),
            
'r' => array('рубль''рубля''рублей'),
            
'k' => array('копейка''копейки''копеек'),
        ),
        
        
'rank' => array(
            
=> array('штука''штуки''штук'),
            
=> array('тысяча''тысячи''тысяч'),
            
=> array('миллион''миллиона''миллионов'),
            
=> array('миллиард''миллиарда''миллиардов'),
        ),
    
        
'nums' => array(
            
'0' => array( '''десять'''''),
            
'1' => array( 'один''одиннадцать''''сто'),
            
'2' => array( 'два''двенадцать''двадцать''двести'),
            
'1f' => array( 'одна'''''''),
            
'2f' => array( 'две'''''''),
            
'3' => array( 'три''тринадцать''тридцать''триста'),
            
'4' => array( 'четыре''четырнадцать''сорок''четыреста'),
            
'5' => array( 'пять''пятнадцать''пятьдесят''пятьсот'),
            
'6' => array( 'шесть''шестнадцать''шестьдесят''шестьсот'),
            
'7' => array( 'семь''семнадцать''семьдесят''семьсот'),
            
'8' => array( 'восемь''восемнадцать''восемьдесят''восемьсот'),
            
'9' => array( 'девять''девятнадцать''девяносто''девятьсот')
        )
    );
    
    public static function 
get($str
    {
        
$def =& self::$def;
        
$res = array();
        
$group preg_split("/\D+/"$str);
        
        if (
count($group) < 3//деньги
        
{
            
$res[] = self::get_one($group[0], $def['words']['r']);
            
$def['rank'][0] = $def['words']['k'];
            
$res[] = self::num2word($group[1]);
        }
        else 
//время - дата
        
{
            
$group array_reverse($group);    
            foreach (
$group as $key => $value
            {
                if (
trim($value)) 
                {
                    
$def['rank'][0] = $def['words'][$key];
                    
$res[] = self::num2word($value0);
                }
            }
            
$res array_reverse($res);
        }
        return 
implode(' '$res);
    }
    
    public static function 
get_one($num$words = array()) 
    {
        if (
count($words)) self::$def['rank'][0] = $words;
        
$str number_format($num0''',');
        
        
$r explode(','$str);
        
$r array_reverse($r);
        
$word = array();
        
        foreach(
$r as $key => $value
        {
            
$word[] = self::num2word($value$key);
        }
        
        
$word array_reverse($word);
        return 
implode(' '$word);
    }
    
    private static function 
num2word($str$key null
    {
        if (
intval(trim($str)) === && $key !== 0) return '';
        
$def self::$def;
        
$nums $def['nums'];
        
$forms $def['forms'];
        
$rank $def['rank'];

        
$dig str_split(sprintf('%02d'$str));
        
$dig array_reverse($dig);
        
//если нет ключа, вернуть цифры с правильной plural-формой (можно использовать для копеек)
        
if (!isset($key)) return $str ' ' . ((== $dig[1]) ? $rank[0][2] : $rank[0][$forms[$dig[0]]]);
        
//если кончился запас "миллионов", вернуть цифры
        
if (!isset($rank[$key])) return $str;
        
$rank $rank[$key];
        
        
$f = (preg_match("/[ая]$/"$rank[0]) && ($dig[0] == || $dig[0] == 2)) ? 'f' '';
        
        if (
== $dig[1]) 
        {
            
$num_word $nums[$dig[0]][1];
            
$word $rank[2];
        }
        else 
        {
            
$num_word $nums[$dig[1]][2] . ' ' $nums[$dig[0] . $f][0];
            
$word $rank[$forms[$dig[0]]];
        }
        
        
$sotni = (isset($dig[2])) ? $nums[$dig[2]][3] . ' ' '';
        if (!
trim($num_word)) $num_word '0'//это для секунд (рубли сюда не доходят)
        
return $sotni $num_word ' ' $word;
    }
    
}

//Бонус: "нативный" time_diff()

function n_time_diff ($d1$d2 null)
{
    if (empty(
$d2)) $d2 date('Y-m-d H:i:s');
    
$time2 strtotime($d2);
    
$time = (strtotime($d1) - $time2);
    
    if (
$time 0) return '00:00:00';
    
$Y gmdate('Y'$time) - gmdate('Y'0);
    
$m gmdate('m'$time) - gmdate('m'0);
    
$d gmdate('d'$time) - gmdate('d'0);
    
$h gmdate('H:i:s'$time);
    
    
$curr_m date('m'$time2) - 1;
    
$delta_m = array(1, -210101101011, -210);
    
$days_0 array_slice($delta_m0$m);
    
$days_real array_slice($delta_m$curr_m$m);
    
$days_corr array_sum($days_real) - array_sum($days_0);
    
    
$d -= $days_corr;
    if (
$d 0) {
        
$d 30 $delta_m[$curr_m] + $d;
        
$m -= 1;
    }
    if (
$m 0) {
        
$m 11;
        
$Y -= 1;
    }
    
    return 
"$Y-$m-$d $h";
}

//это для вывода на экран php-кода // 
print '<h3>Исходный код:</h3>'////
highlight_file(__FILE__); /////////
//При использовании скрипта в другом месте убрать!!