Профилактика "Один час" "Один минут" "Один день" - PullRequest
3 голосов
/ 07 августа 2009

Если мой код выглядит так:

if($seconds < 60)
  $interval = "$seconds seconds ago";
else
 if($seconds < 3600)
     $interval = floor($seconds / 60) . "minutes ago";
else
    if($seconds < 86400)
         $interval = floor($seconds / 3600) . "hours ago";
    else
         $interval = floor($seconds / 86400) . "days ago";

Как бы мне избавиться от всего этого, говоря:

1 дней назад. 1 лет назад 1 минуту назад 1 час назад.

Спасибо:)

Ответы [ 7 ]

7 голосов
/ 07 августа 2009

Если ваше приложение интернациональное и использует расширение gettext, вы можете сделать что-то вроде этого:

sprintf(ngettext('%d minute', '%d minutes', $amount), $amount);

Вы можете создать для него функцию-оболочку:

function pluralize($singular, $plural, $num) {
  return sprintf(ngettext($singular, $plural, $num), $num);
}

Это лучший способ, имо.

7 голосов
/ 07 августа 2009

Может быть сделано очень кратко с троичным оператором:

if($seconds < 60) {
    $interval = "$seconds second" . (($seconds != 1) ? "s" : "") . " ago";
} else {
    if($seconds < 3600) {
        $minutes = floor($seconds / 60);
        $interval = "$minutes minute" . (($minutes > 1) ? "s" : "") . " ago";
    } else {
        if($seconds < 86400) {
            $hours =  floor($seconds / 3600);
            $interval = "$hours hour" . (($hours > 1) ? "s" : "") . " ago";
        } else {
            $days = floor($seconds / 86400);
            $interval = "$days day" . (($days > 1) ? "s" : "") . " ago";
        }
    }
}
3 голосов
/ 07 августа 2009

Еще одно решение.

if($seconds < 60)
  $interval = "$seconds second";
 else
   if($seconds < 3600)
     $interval = floor($seconds / 60) . " minute";
   else
     if($seconds < 86400)
       $interval = floor($seconds / 3600) . " hour";
     else
       $interval = floor($seconds / 86400) . " day";
$interval .= (reset(explode(" ", $interval)) != 1 ? "s" : "")." ago";
2 голосов
/ 07 августа 2009
$time = "120";
$array = array("second" => 1,
               "minute" => 60,
               "hour" => 60,
               "day" => 24,
               "year" => 365);
$old_time = 0;
$old_type = false;

// Loop through each type
foreach($array as $type => $seconds)
{
    // Divide
    $time = floor($time/$seconds);
    // If it went into a value lower than 0, stop dividing
    if($time < 1)
    {
        $time = $old_time;
        $type = $old_type;
        break;
    }
    else
    {
        // Continue dividing.
        $old_time = $time;
        $old_type = $type;
    }
}
if($time == 1)
{
    $interval = $time . " ". $type . " ago";
}
else
{
    $interval = $time ." " . $type . "s ago";
}
echo $interval;

Это делит на все возможные типы времени и дает тот, который не превращает его в дробь. Отделив числовое значение от типа, мы можем проверить, является ли число == 1, и исправить слово.

1 голос
/ 07 августа 2009
if ($interval < 60) {
    $unit = 'Second';
} else if ($interval < 1440) {
    $unit = 'Minute'; $interval /= 60;
} else if ($interval < 86400) {
    $unit = 'Hour'; $interval /= 1440;
} else {
    $unit = 'Day'; $interval /= 86400;
}
$interval = intval($interval);
$interval = "$interval  $unit" . ($interval == 1 ? '' : 's') . " ago";
0 голосов
/ 07 августа 2009

Вот общий PHP-фрагмент для получения строк типа «1 месяц, 2 недели и 30 секунд назад».

$timeUnits = array("month" => 2592000,
                  "week" => 604800,
                  "day" => 86400,
                  "hour" => 3600,
                  "minute" => 60,
                  "second" => 1);

$tmpSeconds = $seconds;

$timeAgoStrings = array();

foreach ($timeUnits as $name => $numOfSeconds) {
   if ($seconds > $numOfSeconds) {
      $val = floor($tmpSeconds / $numOfSeconds);
      $agoStr = ($val > 1) ? $name."s" : $name;
      $timeAgoStrings[] = "$val $agoStr";
      $tmpSeconds = $tmpSeconds - $val; // cut the used time units off our tmpSeconds variable
   }
}
//check if we have more than one string - in case we do then we will pop the last val and add an "and" prefix before the last val instead of a comma
if (count($timeAgoStrings) > 1) {
   $lastString = array_pop($timeAgoStrings);
   $timeAgoStr = implode(", ",$timeAgoStrings)." and $lastString ago";
} else {
   $timeAgoStr = $timeAgoStrings[0]." ago";
}

0 голосов
/ 07 августа 2009

Учи математику.

else if($seconds < 120)
     $interval = "1 minute ago";
else if($seconds < 172800)
     $interval = "1 day ago"

и т.д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...