2017-10-06 4 views
2

非常に長い時間が経っていて、まだphpには比較的新しいので、私は以下のコードブロックを作成して犬と子犬の年齢を計算しました。異なるライフステージの間に、年齢は、数日、数週間、数日、数週間、および最終的には数年および数ヶ月ごとに異なって測定されます。PHPの数量に基づいて日、週、月の単語を複数にする方法

私は現在、次のコードで対処する必要がある2つの問題があります。

  1. 結果は、私はこの場合、月に「2年1ヶ月間」への出力を変更するのに十分なスマートにするためのコードを必要とし、「2年1カ月」であってもよいが、単数なしで年齢の出力に依存's'。私は年、月、週、日に同じことをする必要があります。かなりの量のコードを膨らませてこれを行うことができるのは分かっていますが、それを行うためのきれいな方法があると確信しています。

  2. はまだ関数に渡された日付が過去や未来であるかどうかを確認する方法を見つけ出すことはできません(そのような子犬のごみとして2週間で行う)コードが

  3. より普遍的なできるように

私はコンピュータの記憶がkbで測定されてから、あなたがISAMデータセットのためにナビゲートしてプログラムできるならば、あなたは「上級プログラマー」だったからです。

function CalcAgeDOB($DOBdate) 
{ 
    date_default_timezone_set("America/Chicago"); 
    $datetime1 = date_create($DOBdate); 
    $datetime2 = date_create(); 
    $DifferenceFormatDays = "%a"; 

    $interval = date_diff($datetime1, $datetime2); 

    $TotalDays = (($interval->format($DifferenceFormatDays))); 

    Switch ($TotalDays) { 
     case ($TotalDays < 0): 
      $ReturnText = "We are still waiting on arrival"; 
      break; 
     case ($TotalDays == 0): 
      $ReturnText = "We were born today"; 
      break; 
     case (($TotalDays >= 1) and ($TotalDays < 31)): 
      $ReturnText = $interval->format("%a Days"); 
      break; 
     case (($TotalDays > 30) and ($TotalDays < 91)): 
      $WholeWeeks = (int)(($TotalDays)/7); 
      $RemainDays = $TotalDays % 7; 
      $ReturnText = "$WholeWeeks Weeks $RemainDays Days"; 
      break; 
     case (($TotalDays > 90) and ($TotalDays < 366)): 
      $MonthDays = $interval->format('%m,%d'); 
      $MonthDaysArray = explode(",", $MonthDays); 
      $WholeMonths = $MonthDaysArray[0]; 
      $WholeWeeks = (int)($MonthDaysArray[1]/7); 
      $ReturnText = "$WholeMonths Months $WholeWeeks Weeks"; 
      break; 
     case ($TotalDays > 365): 
      $ReturnText = $interval->format('%y Years %m Months'); 
      break; 
     default: 
      $ReturnText = "Error"; 
      break; 
    } 

    return $ReturnText;  
} 

echo CalcAgeDOB("02/08/2017"); 

----------------編集10/06/2017 --------------------- ----

@ Cy-Rossignolの変更を実装した後でコードブロックが更新されました。これは質問1を処理しました。関数に渡された日付が過去または将来のものであるかどうかはまだ整理する必要があります。複数の関数も提案から更新され、$数の0を渡すときに空の文字列を返しました。スイッチから推奨/ ififへの制御構造を変換しました。英語の場合

<?php 

function pluralize($quantity, $singular, $plural, $format = '%d %s') 
{ 
    if (empty($quantity)) { 
     return sprintf(""); 
    } 

    if ($quantity === 1) { 
     return sprintf($format, $quantity, $singular); 
    } 

    return sprintf($format, $quantity, $plural); 
} 

function CalcAgeDOB($DOBdate) 
{ 
    date_default_timezone_set("America/Chicago"); 
    $datetime1 = date_create($DOBdate); 
    $datetime2 = date_create(); 
    $DifferenceFormatDays = "%a"; 

    $interval = date_diff($datetime1, $datetime2); 

    $TotalDays = ((int)($interval->format($DifferenceFormatDays))); 

    if ($TotalDays < 0) { 
      $ReturnText = "We are still waiting on arrival"; 
    } elseif (empty($TotalDays)) { 
      $ReturnText = "We were born today"; 
    } elseif (($TotalDays >= 1) and ($TotalDays < 31)) { 
      $ReturnText = pluralize(($TotalDays % 7), 'Day', 'Days'); 
    } elseif (($TotalDays > 30) and ($TotalDays < 91)) { 
      $ReturnText = pluralize(((int)($TotalDays/7)), 'Week', 'Weeks') . ' ' . pluralize(($TotalDays % 7), 'Day', 'Days'); 
    } elseif (($TotalDays > 90) and ($TotalDays < 366)) { 
      $MonthDays = $interval->format('%m,%d'); 
      $MonthDaysArray = explode(",", $MonthDays); 
      $WholeMonths =(int)($MonthDaysArray[0]); 
      $WholeWeeks = (int)($MonthDaysArray[1]/7); 
      $ReturnText = pluralize($WholeMonths, 'Month', 'Months') . ' ' . pluralize($WholeWeeks, 'Week', 'Weeks'); 
    } elseif ($TotalDays > 365) { 
      $YearsMonths = $interval->format('%y,%m'); 
      $YearsMonthsArray = explode(",", $YearsMonths); 
      $WholeYears = (int)($YearsMonthsArray[0]); 
      $WholeMonths = (int)($YearsMonthsArray[1]); 
      $ReturnText = pluralize($WholeYears, 'Year', 'Years') . ' ' . pluralize($WholeMonths, 'Month', 'Months'); 
    } else { 
      $ReturnText = "Error";    
    } 

    return $ReturnText; 

} 



echo CalcAgeDOB("7/3/2016") 

?> 
+0

'$ TotalDays'が' 0'のときは '' ''と評価されますが、 '($ TotalDays == 0)'は '' true''と評価されるので、 'switch'文は、変数が* equal *である可能性のある値を比較することによってフローを制御することを意図していますが、その値をそれぞれの' case'ブランチの式の 'switch'ロジックの外部の2次的値と比較しています。これは、PHPの動的な性質のおかげで大部分は機能しますが、副作用として間違いを隠します。代わりに 'if ... else'ブロックの使用を検討してください。 –

+0

[switch() ']の[PHPドキュメント](http://php.net/manual/en/control-structures.switch.php)を参照してください。 –

答えて

0

、我々は、提供量に基づいて単語の適切な形式を選択する簡単な関数記述することができます。

function pluralize($quantity, $singular, $plural, $format = '%d %s') 
{ 
    if ($quantity === 1) { 
     return sprintf($format, $quantity, $singular); 
    } 

    return sprintf($format, $quantity, $plural); 
} 

ここではいくつかの使用例があります:

pluralize(5, 'child', 'children');    // "5 children" 
pluralize(1, 'foot', 'feet');     // "1 foot" 
pluralize(0, 'day', 'days');     // "0 days" 
pluralize(3, 'person', 'people', '%2$s: %1$d'); // "people: 3" 

最後の例は、sprintf()で許可されているカスタム形式を示しています。ここでは、質問から例の機能を使用することができます方法は次のとおりです。

function CalcAgeDOB($DOBDate) 
{ 
    ... 
    switch ($TotalDays) { 
     ... 
     case (($TotalDays > 30) and ($TotalDays < 91)): 
      $ReturnText = pluralize((int)($TotalDays/7), 'Week', 'Weeks') 
       . ' ' . pluralize($TotalDays % 7, 'Day', 'Days'); 
      ); 
      break; 
... 

日付で作業している場合は、偉大な、表情豊かなAPIとPHPの日付と時刻の機能をラップCarbonライブラリを使用することを検討してください:

$dob = Carbon::parse('2017-10-01 00:00:00'); 

$dob->diffInDays(Carbon::now()); // "5" 
Carbon::now()->diffForHumans($dob); // "5 days ago" 

このライブラリは、上記のpluralize()機能と組み合わせて使用​​できます。

関連する問題